On Scheme

Thoughts on Scheme and teaching Scheme

Convincing Programmers They Want To Use Lisp

Posted by Peter on April 7, 2006

A reader commented yesterday that one, unmentioned, barrier to the adoption of Lisp as a universal language is convincing programmers of other languages that Lisp is a better choice. Its hard enough to convince someone to move from one language to another when they look the similar, for example from C to C++, so convincing someone that they want to use Lisp is even harder than normal.

Everyone says how elegant Lisp syntax is and how useful functional programming is. This may be true but it is definitely not convincing to the experienced programmer. The experienced programmer is not intimidated by complicated code, which can have its own kind of elegance, what they want is safety, readability, and extensibility.

For example you may, badly, try to convince them that Lisp is better by showing them how a universal map function is easier to write.
Your example may look like the following:

(define map
  (lambda (function first rest combine list)
    (if (null? list)
        '()
        (combine (function (first list)) (my-map function first rest combine (rest list))))))

You point out the elegance of this, how its operation is extendable to any kind of data structure, for example it can be called on lists as follows: (map (lambda (x) (+ 1 x)) car cdr cons '(1 2 6 7)), and expect the beauty of first order functions to win the programmer over.

However the programmer responds with the following:

interface ConCell<T>
	{
	public T car();
	public ConsCell<T> cdr();
	static public ConsCell<T> cons(T a, ConsCell<T> b);
	}

interface ElementFunction<A, B>
	{
	static public A operate(B x);
 	}

class Map<A, B>
	{
	public static ConsCell<A> doMap(ElementFunction<A, B> func, ConsCell<B> list)
		{
		if (list)
			{
			return ConsCell<A>.cons(func.operate(list.car()), Map<A, B>.doMap(func, list.cdr()));
			}
		else
			{
			return null;
			}
		}
}

Yes, the definition is much longer, but it can be called in the same basic way: Map<int, int>.doMap(myAdditionFuncion, NumList.MakeList(1, 2, 6, 7));. The experienced programmer doesn’t care that the definition is substantially longer, since they can use it in their code in basically the same way. In fact they may prefer their definition because it is both type safe and extendable. For example if you wanted every member of the data structure to implement an index function you could add public int index(); to the cons cell definition, and either force structures to implement it or throw an exception. Yes the same extensibility, and possibly type safety as well, could be accomplished in Lisp using an object system, but then your definition of map is not much shorter or more elegant than theirs.

Now that I have demonstrated the wrong way of doing things what is the right way? The right way is to show them macros. Give the example of a networked file system, where when you open a remote file you send the in use message, and when you close it you send the finished message. Thus in the code you will see a lot of the following pattern:

SendInUseCommand(f);
…
SendClosedCommand(f);

All it takes is to forget to send the closed notification once and you have a hard to find bug on your hands. The experienced programmer knows that while they may always remember to do this, since they wrote the system, their colleagues may not. Now show them the following macro:

(defmacro with-net-file
  (lambda (file &rest body)
    `(progn (OpenNetFile file) ,@body (CloseNetFile file))))

Now to write their network file operations you write:

(with-net-file f
   …)

And now no one can forget to close the file, plus it’s shorter as well. There is no way to do this in a non Lisp language. The closest you can come is to create an object whose constructor sends the open command and destructor sends the closed command, but even this approach has problems. Languages such as Java don’t have reliable destructors, so this option is flat out for them. In other languages you can either create the object on the stack, which means that the file will be in use for the entire function call, which is definitely not desirable (maybe a function called within it wants to open the same file, and you only needed the file for the very beginning of the function), but the only other alternative is to dynamically create and destroy the object when you need it which has the same problem, the programmer needs to remember to dynamically destroy it.

Once you have caught the programmer’s interest with simple macros show them some other cool things they can do, like language extensions. Experienced programmers are always looking for more control, and macros give it to them. Later you can tell them that functional programming is cool too, but they probably won’t need that incentive.

On a personal note macros are what convinced me to move to Lisp. For the longest time I was a C++ programmer. Even though I had seen some Scheme and Lisp back in school it never grabbed me, probably because they didn’t mention macros. However once I read On Lisp, and saw how cool macros were I was hooked. Why I ended up favoring Scheme, with its ugly and complicated macro system instead of Common Lisp is a story for another day however.

Advertisements

29 Responses to “Convincing Programmers They Want To Use Lisp”

  1. Dan said

    Nice blog. I learned Scheme the the good old fashioned way and I taught me a LOT about structure and process and made me a much better developer. IMHO though, development today is more about maintainability than anything else. Sure performance is important, but let’s face it, there’s so much computing power available, that even average programmers are unlikely to run into problems created by their code that more computing muscle can’t hide.Maintenance is everything. And I don’t find that Scheme is that maintainable because the code is not as clear. Consider this example from the book:

    (define (f x y)
    (let ((a (+ 1 (* x y)))
    (b (- 1 y)))
    (+ (* x (square a))
    (* y b)
    (* a b))))

    Granted I’m years removed from the last Scheme I wrote, but that’s less than clear. And as a professional developer, I’m more worried about my code being maintained by someone other than me. And if that’s what I want, how could I in good conscience screw my employer by writing something in scheme. I can guarantee that my employer can find a Java or C or PERL consultant for hire to come in and work on some code when I finally win the lottery. But Scheme?
    So to get to the point of your post — if you want to convince developers to learn Scheme, don’t suggest that it’s practical, because it’s not. The thing that sold me on Scheme was that it was necessary to know Scheme to understand the art and elegance of computer science. I think if you want to be the “Scheme Evangelist,” you’re going to have to gussier her up a bit:
    She’s the classy broad that’s unattainable by most — but for a select few, she’s the best they’ll ever have.

    Thanks for the good read

  2. Dan said

    A few more thoughts — you call java slow in a few places in previous posts. That is very outdated.

    Also, I’d love to hear what you think about Dylan. If it’s in a previous post, I could not find it by searching on Dylan

  3. Dominik said

    I’m trying to convince myself that macros can do stuff you can’t do with higher order functions (and possibly lazy evaluation semantics) just as easily (for some definition of easy.)

    Can anybody explain to me what you can do with this macro:


    (defmacro with-net-file
    (lambda (file &rest body)
    `(progn (OpenNetFile file) ,@body (CloseNetFile file))))

    And you can’t do with this procedure:


    (define with-net-file
    (lambda (file proc)
    (OpenNetFile file)
    (proc file)
    (CloseNetFile file)))

    Cheers,
    Dominik

  4. Peter said

    For Dominik
    Yes, you could do the same thing with such a procedure, but there are two reasons to prefer the macro as a solution. One is that it’s not as elegant to use. I know that sounds stupid, but in essence the functional solution trades off the cost of writing a function call for the cost of writing a lambda expression. Secondly it is less efficient. In the code whenever the functional solution is used there is the cost of the lambda call, to generate the function being passed, and then there is the cost of the additional call to this generated function. So the real question is not why use the macro instead of the functional solution, but why use the functional solution when the macro is faster and smaller? In some sense this is a moot point however, since the programmers you are convincing to use lisp don’t have the functional solution available either.

  5. Peter said

    For Dan:
    As for maintainability I think that Lisp, properly indented and commented is maintainable as any other language. Personally I think your example would have been easy to understand if there had been a leading comment saying what the function did, and if the variables were named meaningfully. On the other hand people seems to love Perl, a horrible language for maintenance, so it might not even matter.

    As for Dylan, well I think it is like an uglier version of Lisp. Practically I would stay away from Dylan at the moment because it has no continuations, but those could always be added later. In terms of “ugliness” I think it suffers greatly from not having a unifying syntax concept. For example Lisp has the (function params …) idiom which everything is expressed in, and Smalltalk has the message passing style which is almost as universal. Dylan on the other hand seems to lack such a principle, which makes it a little ugly looking, and ugliness of this kind makes the language hard to learn, and sometimes hard to use. For example Perl suffers from this same problem. So while Dylan has some good features I think they either need to take their language farther than Lisp, i.e. it has new idioms/features that Lisp can’t easily imitate, like macros are to most other languages, or it needs to clean up its syntax to make it easier to use than Lisp.

  6. Peter said

    On Java being slow:
    See my older piece called Four Kinds Of Slow. My eperiance with Java, not benchmarking Java, tells me that Java often suffers from poor start-up speeds, hogs resources, and often the user interface can become unresponsive (although this may be a symptom of resource hogging by some programs). Not all Java programs are equally bad, but Java could really benifit from losing some weight so that it starts quickly and runs in a small space. If Java is ever going to replace C++ its programs need to be comparable in all aspects, not just the speed of computation.

  7. Peter wrote:

    Yes, you could do the same thing with such a procedure, but there are two reasons to prefer the macro as a solution. One is that it’s not as elegant to use.

    I assume you mean that it is semi-ugly to spell out l-a-m-b-d-a? Is there any lisp-like langauge that has a special function syntax to deal with that? After all, there is special syntax for quasiquote, etc. Why not for something as fundamental as functions? Haskell does a pretty good job at this.

    Secondly it is less efficient. In the code whenever the functional solution is used there is the cost of the lambda call, to generate the function being passed, and then there is the cost of the additional call to this generated function.

    Let’s ignore the fact that the example deals with system calls and I/O which will be hundreds of thousands of times slower than a function call. Wouldn’t that extra function call be about the easiest thing for even a crummy compiler to optimize away?

    So the real question is not why use the macro instead of the functional solution, but why use the functional solution when the macro is faster and smaller?

    Why? Because functions are values that can be passed around like any other value…


    (map with-net-file list-of-files list-of-procedures)

    …whereas with a macro, you’d have to wrap things up in a lambda.

    In some sense this is a moot point however, since the programmers you are convincing to use lisp don’t have the functional solution available either.

    That set of programmers might be shrinking though, with libraries like Boost.Lambda and FC++ creeping into mainstream languages. Anyway, as long as you are trying to convert people with macros, I don’t think it can do harm to also tell them that languages like Scheme/Lisp can not only make their programs shorter, but the languages themselves are orders-of-magnitude simpler than languages like C++/Java, with far fewer hairy corner cases.

    P.S. What about having a “Preview” button?

  8. Peter said

    Using the functional version is “uglier” simply because it makes you type more, not because lambda is an ugly word. As for efficiency never assume that the compiler will optimize something away unless it is part of the language specification (ex: tail recursion), because compilers change. Your arguments against using the macro seem like arguments against using the functional style by procedural programmers. Just as they would insist that everything that can be done functionally can be done procedurally so you are making the claim that everything that can be done with a macro could be done functionally. Yes in both cases the programs can accomplish the same tasks, but by using functional programming and macros your programs are smaller and more elegant. If you don’t care about brevity and clarity why not use assembly?

  9. Using the functional version is “uglier” simply because it makes you type more, not because lambda is an ugly word.

    Hmm. I guess I didn’t make my case very well. It seems like an accident of history that functions are more verbose because you have to spell out “lambda”, while there is short-cut syntax for things like quasiquote and unquote-splicing.

    Yes in both cases the programs can accomplish the same tasks, but by using functional programming and macros your programs are smaller and more elegant.

    I’ll agree with this statement in the most general sense. But I don’t think you’ve demonstrated that with the “with-net-file” example.

  10. If syntax is an obstacle, suggest TwinLisp:

    First comment with math functions
    “””
    (define (f x y)
    (let ((a (+ 1 (* x y)))
    (b (- 1 y)))
    (+ (* x (square a))
    (* y b)
    (* a b))))
    “””
    will look like (if I read Scheme correctly):
    def f(x,y) {
    a=1+x*y
    b=1-y
    x*a**2 + y*b + a*b }

    and defmacro from the article:
    “””
    (defmacro with-net-file
    (lambda (file &rest body)
    `(progn (OpenNetFile file) ,@body (CloseNetFile file))))
    “””

    will be
    mac &with-net-file(file,**body) {
    `progn {
    ($file).OpenNetFile()
    $@body
    ($file).CloseNetFile() }}

    Lisp, in TwinLisp form, looks a lot more “sellable” to C/Java/Python/Ruby crowd, now.

  11. Peter said

    You convince people to stay with a language because of its features, not because it is pretty. People still code critical functions in assembly because sometimes exact control matters, not because assembly is pretty. Thus TwinLisp is not going to have an advantage convincing programmers to permenantly switch to it over some other version of Lisp, since they have the same features. In fact it is going to have additional problems since TwinLisp programmers won’t be able to understand, or use in their programs, the large body of code written in Lisp already. If you really think TwinLisp is better, and you want to win converts, you need to give it new features, not simply fiddle with the syntax of CL.

  12. TwinLisp gives to the rest of the programmers things that are in Common Lisp, but absent from Java, Python. And this is *a lot*.

  13. And ya. TwinLisp is written in such a way, that you *use* already written lisp code.
    For example, load(:file) will try to load twl file, lisp file, or fasl file. Lisp and fasl file do not have to come from translation of a twl file, i.e. it can be some preexisting lisp code.
    I do not like to invent wheels myself, and do not want others to waste their time.
    So, again, 100% of already existing lisp code (and thats a lot), can be and should be used, while programing in TwinLisp.

  14. Peter said

    Yes, but not, for example, continuations, which are in Ruby if I remember. So my question is why not use Ruby instead of Twin Lisp? Why not just use Scheme or Common Lisp? Scheme and Common Lisp have the advantage in that it is clearer what a macro captures. For example you earlier wrote the example: “lst.car().funcall(params).funcall(params2)”. What does a macro on funcall capture here, and in which order are they evaluated? On the other hand if you aren’t a macro person you can use Ruby and you get an awesome web framework that Common Lisp, and hence TwinLisp, doesn’t offer. So why should I use TwinLisp?

  15. 1. Continuations:
    Isn’t Paul Graham wrote in lisp code for continuations in lisp? Since it is a lisp code, you can use it with TwinLisp.
    2. Ruby doesn’t have macros – reason 1. TwinLisp runs on top of Common Lisp, so, it will run on any platform where CL runs now – reason 2. There are implementations with good and bad features, and you choose the one your problem needs. TL will run there. Do you have such choice in Ruby? – reason 3.
    These are my reasons. Notice, that these are the reasons of why I would use Common Lisp. But if I hesitate lisp’s syntax, I’ll go with TwinLisp, especially that it has some extra small pleasant features.
    3. Order of evaluation in “lst.car().funcall(params).funcall(params2)” is the expected one – from left-to-right. But really, it is Lisp’s duty, not TwinLisp’s, and the order is defined by the order in which CL will do funcall(funcall(car(lst),params),params2).
    Java people won’t be confused a bit. Well this alternative syntax is for them.
    4. One might be “not a macro” person. But one should do regular things like code refactoring, etc. Macros let you refactor those places, you cannot refactor otherwise, or those that start to look ugly after refactoring (which is why these places are left behind). Add to this, that, the tighter the code, the more of it (percentage-wise) tested by the tests you write (arguable, though).
    With point 2, I find it a damn good reason to use Common Lisp. And if I or someone else has a *personal* preference, we can write code in TwinLisp.

  16. Peter said

    1- The continuations in Lisp aren’t as powerful as those in Scheme, it requires you to re-write the interpreter to do Scheme macros in lisp
    2- Acutually exposing implentation dependant featiures is a very bad idea, because it means that you can’t write code/libtraries for TwinLisp, but must write code/libraries for “TwinLisp + implementation” which fractures a small initial user base and makes it hard to write documentation, also see point 4
    3- Acutually the order of evaluation of “lst.car().funcall_1(params).funcall_2(params2)” should be “(funcall_2 (funcall_1 (car lst) params1) params2)” which implies that a macro bound to funcall_2 should be activated first with the parameters “(funcall_1 (car lst) params1” and then the macro for funcall_1 may be invoked with the parameters “(car lst) params1”. In TwinLisp it looks like funcall_1 should have its macro inkoked first with the parameters: “(params).funcall_2(params2)” and then funcall_2 should be invoked with “(params2)”. Only one of these interpretations can be right, and if you are sticking with the Common Lisp way than the syntax misleads the programmer as to what is actually going on.
    4- I know macros rock, but if some one thinks that syntax is important enough to prefer TwinLisp over Common Lisp it is reasonable to assume they might prefer Ruby over TwinLisp because Ruby has a syntax they are familiar with, and it has powerful frameworks.

    I think TwinLisp has promise, but it needs to go further. It needs to do more than improve Lisp syntax if it wants to become a serious alternative (for example see Dylan, which improves Lisp’s syntax, has macros, but does OOP as well). People often complain about Lisp’s type system, CLOS, non-hygenic macros, the library system, ect. Fix some of those problems and then you might give people a solid reason to prefer TwinLisp.

  17. Re4:
    If you think that macros rock, it is not logical to prefer Ruby over TwinLisp. The first one has no macros, the last one does. And both have algol-ish syntax. If you talk about libraries, then it is another story – prefering macros over Rails, or something like it.
    Re2:
    Sometimes languages cannot hide that they run on a particular OS. Same applies to TwinLisp+CommonLisp, in a way.
    But then, you’ve got choice.
    Today, if I write Lisp code, I have to be careful for what implementation it is, even with ANSI standard. So, with TwinLisp I am in the same water. But, I never claimed that I wanted to change this situation with TwinLisp, i.e. TwinLisp does not address negative sides of a multitude of CL’s implementations.

    TwinLisp uses CLOS. Macros are CL’s, thus, non-hygenic, but there is a small feature in TwinLisp, that will make writting macros a little safer (but just a little 🙂 ). If you want to right shorter names for symbols from different packages, you do not have to use interning in TwinLisp, which leaves interning for trully useful places. As I said, there are strawberries on a TwinLisp cake.

    I guess, you assume that TwinLisp should be an alternative to Common Lisp.
    No. An analogy: branches of the tree cannot be an alternative to tree’s roots. In the same fasion, TwinLisp is a new alternative way of *using* CL’s runtime, libraries, language. But TwinLisp is not a substitute of a Common Lisp.

  18. Peter said

    Its not a question of what I want, I like ()s, I think they make the code eassier to read. The problem is getting someone (i.e. a CL user) to adopt a new language/syntax (TwinLisp). You say that TwinLisp’s lack of ()s are a real big seller (for some audiences), and I am claiming that you need substantal, non-syntax, improvements over Common Lisp to convince a programmer to switch from CL to TwinLisp. Also using CLOS is a BAD thing, CLOS is rather outdated, and could use some serious work. Basically I am saying that TwinLisp should be designed as an alternative to CL, not a new implementation/varient of CL, there are enough CL variants as it is, and we could use some improvements, and improvements / cool new features attract programmers. Thats just my opinion, but I have played around with creating languages before (see Centum) so I know some of what not to do.

  19. “””
    The problem is getting someone (i.e. a CL user) to adopt a new language/syntax (TwinLisp).
    “””
    CL user does not have to adopt TwinLisp, he/she is already OK with CL. TL is for Java people to use CL.

    “””
    You say that TwinLisp’s lack of ()s are a real big seller (for some audiences), and I am claiming that you need substantal, non-syntax, improvements over Common Lisp to convince a programmer to switch from CL to TwinLisp.
    “””
    It is not an absence, it is a placement of ()’s. Some people want to see (foo), some want to see foo(). The first ones can use Lisp, the former are deprived. So, TwinLisp is for others.
    I am against syntax holy wars. I want to let people use both. At the end of the day the argument boils down to human subject preferences. TwinLisp gives you the choice in this preference.
    I do not want people to switch from CL to TL, because TL is already CL (which is why it is called a Twin). But I want Python, Ruby and Java people to switch over to TL (and CL, as a result).

    “””
    Basically I am saying that TwinLisp should be designed as an alternative to CL, not a new implementation/varient of CL, there are enough CL variants as it is.
    “””
    a) If it should be, you are welcome to take syntax (code is GPL-ed) and put *proper* internals as you see it.
    b) There is CL, Scheme, whatever. But there is no one intuitive for a pythonist, which has *all* goodies of a fat CL. TwinLisp solves a human problem, making CL pleasant and accessable to Java/Python people.

    As for CLOS, I cannot comment on it. But I have built TwinLisp using it. If it were a message-passing thing, then TL would not be possible without digging internals of the lang. So, I have exloited CLOS here.

    Artificially, it looks as if TwinLisp is a new language. If language is taken in the narrow sense as just a syntax, then yes. If you take language to mean more, like runtime and libs, then TwinLisp is not a language. It is a horrible hack on top of Common Lisp, which brings syntax and some tricks in.

  20. dgtized said

    While I realize that it doesn’t result in the same set of code since you are forever passing in anonymous blocks the following code in ruby does in fact do something very similar without any destructors. In fact most languages support some idiom like this if they include any form of an anonymous lambda:

    def with_net_file(file)
    OpenNetFile file
    yield file
    CloseNetFile file
    end

    to use it:

    with_net_file(file) do |f|
    do_stuff(f)
    end

    in fact most ruby libraries make frequent use of this idiom. The default ruby open either returns an explicit file or yields to a block and cleans up after itself. Note that the {|x| } form is the same as the do |x| end form and is more commonly used for single line blocks. The open command in ruby actually yields the file within exception handling code so that the file will get closed correctly even if the block passed has an exception.

    print open(“filename”) {|f| f.read}

    would print the contents of filename.

    Note that similar scheme code would be

    (define with-net-file
    (lambda (file block)
    (OpenNetFile file)
    (block file)
    (CloseNetFile file)))

    (with-net-file file (lambda (f) (read f)))

    There are certainly times while coding ruby that I very much wish for macros, often they are alleviated by some tricky use of eval, but macro’s would at times be nice. This problem however, is not one that I feel macro solve in a clean manner. For one your body code always needs to lexically capture file in order to do anything with it. Macro’s are definitely nice, but I think a more compelling example is in order. The above idiom using anonymous lambda’s actually works even in java using anonymous inner classes. As many things in java it is simply too verbose to feel like any sort of savings so it’s not particularly useful, but it is possible. Claiming it is impossible to fix that particular problem without lisp is not giving credit to other languages where it is due.

    For the record I hold scheme and ruby to be my two favorite languages and I certainly hope for more lisp/scheme code in production so this is not intended as anti-lisp, merely acknowledgement of where other languages aren’t completely limited in comparison to lisp.

  21. Peter said

    I have to admit Ruby is a language with a lot of potential. It still has some problems of course, but there is some indication that the creator is actively working on fixing them, which is more than you can sat for the Common Lisp community at the moment. (If you read usenet you know that they are busy flaming anyone who says that Common Lisp could use improvement / has stagnated at the moment.) I’ll look into providing some better examples of the usefulness of macros in a future post.

  22. Eric Mertens said

    I know I’m really late to the party, but I hadn’t read this posting yet. Regarding the use of macros simply for their pass-by-reference semantics instead of for their code-as-data manipulation ability is a losing proposition. Languages like Haskell make thet Lisp macro solution look clunky. There are advantages to trumpet about macros, but pass-by-reference isn’t one.

    (defmacro with-net-file
    (lambda (file &rest body)
    `(progn (OpenNetFile file) ,@body (CloseNetFile file))))

    with_net_file file body = OpenNetFile file >> body >> CloseNetFile file

  23. SOG knives said

    SOG knives…

    Interesting ideas… I wonder how the Hollywood media would portray this?…

  24. Arturo Mieussens said

    It’s been a long time since this conversation was active, but I’ve been thinking of something lately and would like your opinions.

    We have this well known ugly code:

    (define (f x y)
    (let ((a (+ 1 (* x y)))
    (b (- 1 y)))
    (+ (* x (square a))
    (* y b)
    (* a b))))

    Scary, but what if we do some indentation?

    (define (f x y)
    
 (let ((a (+ 1 (* x y)))
    (b (- 1 y)))
    
 (+ (* x (square a))
    
 (* y b)
    (* a b))))

    Better, but I’ll need to count parenthesis to really understand what’s going on. What if we align parenthesis vertically?, at least that way I’ll know what’s inside of what.

    (define (f x y)
    
 (let
    (
    (a (+ 1 (* x y)))
    (b (- 1 y))
    )
    (+
    (* x (square a))

    (* y b)
    
 (* a b)
    )
    )
    )

    Ok, that’s much more like what I’m used to.

    But, there’s potential for DRYing this up, as we have parenthesis and indentation doing the same thing, why not just use one or the other?

    define (f x y)
    
 let
    a (+ 1 (* x y))
    b (- 1 y)
    +
    * x (square a)
    
 * y b

    * a b

    Now that’s something I like, almost Rubysh… there’s the prefix notation thing, but I actually like that.
    The best part is that nothing is changed, only indentation when used substitutes parenthesis, and translation to standard lisp notation is done mechanically following a couple of rules.

    What do you think?

  25. Our older son is far too impatient to sit in the Epsom salt baths. We finally gave up a switched to a supplement call methylsulfonylmethane (MSM). It is two methyl groups attached to a sulfoxide group and the body will convert it to sulfate if (a big if) the body’s transulfuration pathway is working correctly. It worked great for our son, no more red ears and a significant improvement in his chronic allergic shiners.

  26. Christopher Jefferson said

    In C# there is ‘using’, and in C++ there is the RAII (Resource Acquisition Is Initialisation) idiom. Both seem to offer identical functionality to this. I’m sure there is something similar in python too, although I am not familar with python.

  27. […] This post was mentioned on Twitter by Hacker News YC and felice, Kalimba HN. Kalimba HN said: Convincing Programmers They Want To Use Lisp http://goo.gl/fb/zGAd9 #hackernews #kalimba […]

  28. bored said

    bored…

    […]Convincing Programmers They Want To Use Lisp « On Scheme[…]…

  29. Bishop was arrested dexter mo newspaper obituaries in August along with her
    father while vacationing.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: