jes5199@electra:~/code/scala$ time scala hello.scala
Hello, world!
real 0m24.380s
user 0m0.564s
sys 0m0.036s
Monday, December 29, 2008
this is going to be a problem
Sunday, December 28, 2008
Flickr reverse lookup bookmarklet
flickr reverse lookup bookmarklet
If you're on a flickr jpg and you want to get to the photo's page, click this bookmarklet. It's that simple.
If you're on a flickr jpg and you want to get to the photo's page, click this bookmarklet. It's that simple.
Friday, December 12, 2008
semicolon semicolon
On wednesday, Kim Wallmark, Arlo Belshee, and I entered a quick little programming competition at Cubespace's Coder Social. We were encouraged to pick a programming language that we weren't terribly familiar with -- most of the teams seemed to be Ruby programmers trying Python or Python programmers trying Ruby. That didn't seem like a challenge to us, so we went with F# -- fortunately Kim already had an F# IDE installed, but otherwise none of us had ever used it.
The problems were all from Project Euler, so they were the sorts of things that tend to have deeply recursive solutions. So, in that department, F# was an advantage.
F# has some unpleasant quirks, though:
We had this function:
By default, it only works on ints! It should be valid for any numeric type! It's just addition! But no, we had to label the parameters:
Maybe I've been spoiled by Haskell, but I just assume that if I've got type inference, I've got Hindley–Milner over the entire program. In F#, types are only inferred within the boundaries of a single function. That means more type annotations.
And for some reason I don't understand, by default recursion is forbidden in a function, unless you define it with the "let rec" keyword. I have no idea why.
Since F# is on the CLR, it inherits some VM design smells. Where's the Bigint type? Microsoft.FSharp.Math . You know, I would have expected the F# language to have implicit access to the FSharp namespaces. Nope.
We knew about the confused usage of ;; for end of line and ; for comma, and , for a different kind of comma. But we kept having to look up operators (for method names we had autocomplete in the IDE! but dingbats were Google's territory.) I know we got confused on: cons (::), append (@), exponent (**), mod (%).
And when you get it wrong, the interpreter is worthless. It had a tendency to entirely fail to parse our functions, and give us line/column numbers at the end of the code, rather than at the problem spot. I can't remember what the messages we were getting said, but it sure seemed like they just said "This is wrong"
Several times we tried googling some common function names like "head" or "tail" or "append" and found that mixed with the keyword "F#" you get nothing but music results. Way to go, marketing wizards.
The problems were all from Project Euler, so they were the sorts of things that tend to have deeply recursive solutions. So, in that department, F# was an advantage.
F# has some unpleasant quirks, though:
Monomorphism by default
We had this function:
let fibStep (a,b) = (b,a+b)
By default, it only works on ints! It should be valid for any numeric type! It's just addition! But no, we had to label the parameters:
let fibStep (a : BigInt ,b : BigInt) = (b,a+b)
Crippled type inference
Maybe I've been spoiled by Haskell, but I just assume that if I've got type inference, I've got Hindley–Milner over the entire program. In F#, types are only inferred within the boundaries of a single function. That means more type annotations.
Recursion requires annotation
And for some reason I don't understand, by default recursion is forbidden in a function, unless you define it with the "let rec" keyword. I have no idea why.
Find the missing library
Since F# is on the CLR, it inherits some VM design smells. Where's the Bigint type? Microsoft.FSharp.Math . You know, I would have expected the F# language to have implicit access to the FSharp namespaces. Nope.
Unusual punctuation
We knew about the confused usage of ;; for end of line and ; for comma, and , for a different kind of comma. But we kept having to look up operators (for method names we had autocomplete in the IDE! but dingbats were Google's territory.) I know we got confused on: cons (::), append (@), exponent (**), mod (%).
Cryptic error messages
And when you get it wrong, the interpreter is worthless. It had a tendency to entirely fail to parse our functions, and give us line/column numbers at the end of the code, rather than at the problem spot. I can't remember what the messages we were getting said, but it sure seemed like they just said "This is wrong"
Hard to google
Several times we tried googling some common function names like "head" or "tail" or "append" and found that mixed with the keyword "F#" you get nothing but music results. Way to go, marketing wizards.
Wednesday, December 3, 2008
baby's first spammer
the wiki that I'm hosting ( pdxipedia ) got a nice annoying spam infection. Mediawiki may be the world class software behind Wikipedia, but out of the box it's spambait. We're lucky only one got in (Hi, 194.165.42.59 ! How are things in [consults GeoIP], uh, Saudi Arabia? How's the business of ... jeeze these spams seem to be total nonsense ... search engine disruption? )
Today, I signed up for Project Honeypot, which keeps a blacklist of spammers. There's a plugin for Mediawiki that redirects known spammers away, and it's also supposed to have invisible honeypot links to ensnare unknown robots. The link generation is buggy though, so I'm not brimming with confidence about the whole thing.
So I wrote a script that runs through my Lighttpd access.log files (it probably would work for apache, too), and checks IPs of all the recent visitors against the Project Honeypot blacklist. If there's a match, I use iptables to block that IP. I've got it running once a minute -- that's still enough time for a fast bot to do some damage -- so it's not really going to be a complete solution, but it could potentially prevent denial-of-service caused by a persistent bot.
Today, I signed up for Project Honeypot, which keeps a blacklist of spammers. There's a plugin for Mediawiki that redirects known spammers away, and it's also supposed to have invisible honeypot links to ensnare unknown robots. The link generation is buggy though, so I'm not brimming with confidence about the whole thing.
So I wrote a script that runs through my Lighttpd access.log files (it probably would work for apache, too), and checks IPs of all the recent visitors against the Project Honeypot blacklist. If there's a match, I use iptables to block that IP. I've got it running once a minute -- that's still enough time for a fast bot to do some damage -- so it's not really going to be a complete solution, but it could potentially prevent denial-of-service caused by a persistent bot.
Tuesday, November 25, 2008
I can't yet call it Jes' Law
Has this been said before?
I've seen this both at work and on some personal projects lately.
At work, we're adding an API to a PHP application so that we can control it from Ruby on Rails -- the API layer is supposed to be thin and clean, so we can do all of the complicated logic in Rails. Even so -- I've spent 90% of my time in PHP-land for the last month.
I just threw together a toy at http://jes5199.com/sunrise/ . I needed a calculator that could predict sunrises, and the first thing I found was a CPAN module DateTime::Event::Sunrise. But suddenly my light little Sinatra and Javascript app includes a nightmarish perl script and a patched version of the Sunrise library, since the package is abandoned and mildly broken. I spent easily six hours in perl, compared to two hours doing everything else. And I'm still not certain that there aren't edge cases where a sunrise gets skipped.
Corollary:
When you're working with more than one tool, the worst tool will use up the most of your time
I've seen this both at work and on some personal projects lately.
Corollary:
If a job has good parts and bad parts, the bad parts will dwarf the good.
Wednesday, November 19, 2008
first post
I want to talk about
- new programming languages
- code tool practices
- disposable software (software as performance art)
- general ranting
Subscribe to:
Posts (Atom)