[x] boot to the head (do it!)
Even though violence solves everything, I think I'd better not.
Well, if *I* managed to make some code, I would be totally proud to have a hacker describe it as "cute," but that's because the closest thing I get to writing code is building a cue list in QLab
I generally describe code as "cute" when it's clever. Which could be positive, if you're being clever to good effect and there's not a good non-clever way to do it. Or it could be a negative, if you're being too clever than necessary and just obscuring what you're trying to accomplish.
As for laughing while they're saying it? That's nuanced too. Code is language. I've seen code that was Shakespeare, code that was James Joyce (ugh), and code that was Feynmann. I've laughed at code because it was clever and unexpected like a good joke. I've also laughed at code because it was a train wreck.
Maybe you should post your code and see if we laugh at it :)
That pretty well describes how I understand the word "cute" in relation to code.
So if they call it cute and they laugh, they appreciate something in your code. It sounds like in this case it was perhaps not the same quality that you appreciated about it. And do remember, they're laughing at your code, not at you.
The homework problem was:
Define a function
lex that takes a lambda-calculus expression, and returns the same expression with all variable references replaced by lists of two elements whose car is the symbol
var and whose cadr is the lexical address of the referenced variable. Each free variable is similarly wrapped within a list whose car is the symbol
Now, it just so happened that, earlier in the same homework, we'd been asked to define a function
free which takes an expression and returns a list of the variables that occur free in that expression, and a another function
bound which does the same thing for variables that occur bound. They work by breaking an expression down into symbols and building an environment list as you go along (which normal people would call a "symbol table", I think). I figured that
bound each did some of the work that
lex would have to do, so my
lex looks like this (note the calls to
(letrec ((lex (lambda (exp orig-exp count)
[,y (guard (symbol? y))
(cond ((member? y (free orig-exp)) `(free-var ,y))
((member? y (bound orig-exp))
(list 'var count)))]
[(lambda (,x) ,body) `(lambda ,(lex body orig-exp (+ count 1)))]
`(,(lex rator orig-exp count)
,(lex rand orig-exp count))]))))
(lex exp exp -1))))
It didn't occur to me to think about efficiency. In fact, I thought I was doing a Good Thing by reusing code I'd already written! But it turns out that calling
bound on the whole expression, when you could be doing the environment thing right here in
lex, is cute.
2008-10-01 06:48 pm (UTC)
Re: Okay, here it is.
I thought I was making some progress on reading Lisp but this is still impenetrable.
from your description, I think you did the Right Thing.
Also, there's a bug. I have just one counter,
count, that's supposedly keeping track of lexical addresses for everything. My original thought was that we could get away with that, because we want the count for a variable to be increased when we jump over any
lambda, not just one that binds that particular variable. But I forgot that (if my notes are correct) lexical address has to do with wherever a variable was most recently bound. So, if we get to something that was already previously bound, we need the count for that variable to start over again at 0.
So, to fix it, instead of
count, I now have
count-list, an association list of variables to their lexical addresses. (I guess that at this point I might as well call it an environment.) When I see a
lambda I call a helper procedure,
update-count, which itself needs a helper, and...I would post some more code, but it's really getting hairy now.
The more I play with it, the more I see that it really is ridiculously inefficient to call
bound on the original expression. I have all the information I need right inside
lex, if I just think a bit harder about where to find it. But it's probably time for dinner, or something.
And actually, it's now been pointed out to me that the association list is unnecessary because we can store variables in an ordered list and calculate each one's lexical addresses based on its position in the list.
You know, I'm used to being around people who are better programmers than me. But here there are many, many people who are better Scheme programmers than me. I hope I can learn a lot from them.
Amen to this. 'cute' and 'clever' are orthogonal to 'good'. I like seeing cute code though, so if cuteoverload and stackoverflow merged, that would be the best site ever.
Be brave and let us judge it :)
2008-10-01 04:16 pm (UTC)
Generally I use cute to mean "surprising, but not wrong". A laugh means "very surprising".
I'm still trying to get used to the fact that around here, Not Wrong is not good enough.
2008-10-01 09:23 pm (UTC)
Really? Because I generally grade "not wrong" as "correct". Anything else is demanding that students read your mind, which is just rude.
I have laughed at cute assignments and then given them good grades.
Well, okay. What I mean is that not wrong is good enough, but it's not good. I want to be good.
you might be good, but wanting to be good right off the bat is the path to true folly. Look back at code from your first year of remember that in 2 years you'll look back at your current code and say the same things.