flwyd: (daemon tux hexley)
As an avowed introvert, I took the opportunity of the new fewer-social-commitment world of coronavirus stay-home orders to do some fun programming on personal projects, like my Elizabethan curse generator. While working on bash and Tcl implementations I discovered that vim, my favorite text editor, did not automatically remove line continuation characters when performing a join command. In my case, I had copied an array of quoted strings from Python into a shell script, which doesn't need quoted strings, and wanted to realign the declaration to fit nicely in 80 columns, like so:
noun=(apple-john baggage barnacle bladder boar-pig bugbear bum-bailey \
canker-blossom clack-dish clotpole coxcomb codpiece crutch cutpurse \
death-token dewberry dogfish egg-shell flap-dragon flax-wench flirt-gill \
foot-licker fustilarian giglet gudgeon gull-catcher haggard harpy hedge-pig \
hempseed horn-beast hugger-mugger jack-a-nape jolthead lewdster lout \
maggot-pie malignancy malkin malt-worm mammet manikin measle minimus minnow \
miscreant moldwarp mumble-news nut-hook pantaloon pigeon-egg pignut puttock \
pumpion rabbit-sucker rampallion ratsbane remnant rudesby ruffian scantling \
scullion scut skainsmate snipe strumpet varlot vassal waterfly whey-face \
whipster wagtail younker)
Unfortunately, the J command in vim leaves those trailing backslashes (which mean "the command keeps going on the next line") in the middle of the combined line. After a bunch of Googling, I determined that there wasn't a vim setting to do so, and nobody had written a plugin for it either.

So of course I decided that extra home-bound free time meant it was time to learn how to write a vim plugin so that I could change the behavior of the line-joining commands. A couple coworkers mentioned that such a plugin would be even more useful if it could merge strings when joining as well (resulting in "lorem ipsum" rather than "lorem " + "ipsum"). This in turn provided a great excuse to geek out on programming language details on Wikipedia, Rosetta Code and 99-bottles-of-beer.net. And thus was born vim-conjoin, a plugin that remaps J, gJ, and :Join to handle continuation breaks and string concatenation.

This exercise was absolutely a violation of XKCD's Is It Worth the Time graph: I spent the better part of two weekends, plus a few evenings, implementing and testing this plugin (mostly testing). It will, in my lifetime, perhaps save me an hour of work. So hopefully other vim users find it useful, too.

As with any personal programming project, the time wasn't entirely wasted, of course. The next time I want to write a vim plugin I'll have a much better idea of what I'm doing. And I learned more in a couple weeks about vim than I've learned in most individual years in the last two and a half decades I've used the editor. (Though it's going to take me awhile to remember to put call before function invocations and I'm forever forgetting the l: and a: prefixes on local and argument variables.) And the Wikipedia adventures led me to finally read up on INTERCAL a famously obtuse parody language, and LOLCODE, a lolcat-inspired esoteric programming language that I wish I'd heard about in 2007 when it was announced. (LOLCODE unfortunately seems to have been abandoned; the language author hasn't responded to a 2018 proposal for array (BUKKIT) syntax.) And that gave me an idea for an esoteric language of my own that I hope to work out during the remainder of quarantine time…

You do you. And make sure you've got an unnecessarily polished tool while doing so.
flwyd: (java logo)
Originally posted by [livejournal.com profile] bashorg at Bash.org QDB - 950581
< Ergo^> Six Stages of Debugging
< Ergo^> 1. That can't happen.
< Ergo^> 2. That doesn't happen on my machine.
< Ergo^> 3. That shouldn't happen.
< Ergo^> 4. Why does that happen?
< Ergo^> 5. Oh, I see.
< Ergo^> 6. How did that ever work?
< MatthewWilkes> 7. svn blame
< miniwark> 8. one day we will write tests
flwyd: (spiral stone)
Hey kids, it's time once again for the shower meme! [livejournal.com profile] vvvexation asked me the following five questions. If you'd like me to ask you five questions that you'll then post (soliciting interviewees as well), leave a comment on this post.
1. What's your favorite Hitchcock film?
Alfred Hitchcock has an impressive résumé of outstanding films, but Rear Window is my favorite. Like many of his films, it's got great acting, psychological inquiry, shot composition, and suspense building. Rear Window goes beyond the others as a technical masterpiece of storytelling and storyboarding, setting the entire movie in a single room, focused through the titular rear window into an apartment courtyard. While North By Northwest, Psycho, Vertigo, and The Birds are more typically Hitchcockian, I smile the most when I think back to Rear Window.
2. What programming language are you digging the most these days?
I like to say that my favorite programming language is the one that's best suited to the task at hand. I really like Ruby's way of thinking, mixing Perl convenience with Smalltalk object orientation, functional programming encouragement, and enough ninjutsu to make execution painless... or very painful. I've felt a bit let down in Ruby's API offerings on topics that aren't related to Rails; things I want to build on seem half baked.

I really wanted to like Scala, but the "tutorial" I read spent a lot more time showing off cool programming modalities and not enough time showing the reader how to do basic stuff like manipulate collections. So when I encountered the section on right-associative operators and list folding, I stomped off in a huff. I suspect this is more a problem with the documentation than the language itself, so I'm willing to give it another try at some point.

I like some ideas in Google's new Go language. I'm interested to see what folks start doing with that. I'm also interested in Haskell, but its syntax is obtuse to the untrained eye. I'd like to go on a few dates with it and see if we're compatible.

3. What species of animal would you modify, given the chance?
What sort of modifications are we talking about? I like to modify chickens by removing parts of their carcass and subjecting them to heat...

Assuming you mean changes to a species' core DNA, I'd like to debug a few human body problems. For one, our backs are pretty fragile, especially when we do a lot of sitting. For another, some of our social instincts are better suited to small groups and tribes and show flaws in urban settings.

It would also be nice to modify certain types of mosquitoes so they don't act as vectors for malaria. While we're at it, we might want to tweak some megafauna to adapt to human-introduced environment change, though I'm not sure what changes you could make to an elephant to survive habitat and food source loss and still call it an elephant.

4. What would you miss most if you moved away from Boulder?
It would probably depend on where I moved. If I moved to San Francisco, there would still be plenty of smart and creative people. If I moved to Norway, there'd still be plenty of mountainous outdoor activity. If I moved to New Mexico there'd still be plenty of sun and nice weather. If I moved to Hong Kong, there'd still be plenty of interesting world cuisine.

What I missed about Boulder when I was living in the Denver suburbs was bikeability. I learned that I'm not very good at motivating myself for recreational bike rides, but when I can ride across town in half an hour, I'm a lot more liable to hop on a bike than drive my car. Plus, there's a weekly excuse to ride around town and bring smiles to peoples' faces. I also missed the college town/intellectual atmosphere. In college, I would plan my semester's social calendar around the International Film Series on campus, but in the past five years I've watched very few movies. So I'm excited to be back around IFS, CWA, and people who work for CU, NCAR, NIST, and other exciting abbreviated entities.

5. If you were asked to design a monument, what would it look like and who or what would it be a monument to?
The most powerful monument I've ever visited is the temple at Burning Man. It combines beautiful craftwork with powerful statements to build a place which simultaneously provides solitude and community and supports grief and joy. It's typically focused on people who have passed from this life, but it's open enough to allow all kinds of release.

I think it would be interesting to apply the same sense of beauty and community involvement to a living monument of changed places. With a key theme of natural areas destroyed by human development, it could feature maps, images, stories, and facts about the way parts of the world used to be and how they're changing today. Participants could add their own memories of visiting a place and stories passed down when their grandparents moved from the old country. People could expand the idea of changed places to talk about the culture of their old neighborhood, the house they grew up in, and BBSes back in the good ol' days of online communication.

I think such a monument should have an interactive component shared over the Internet. People who can't attend in person can submit their stories and pictures. Periodically, someone would create a video tour, exploring some of the many contributions. People could contribute their stories in audio and video, adding oral history to visual and architectural homages.

You can read my previous answers to shower meme interviews. You can participate by requesting five questions in the comments to this entry.

flwyd: (java logo)
I'm working on some code to integrate our Java system with a 3rd-party COM object. (Yeah, lots of fun.) The COM object is designed to be used in a very procedural style: all methods return a boolean indicating success and provide values using pass-by-reference. If the method fails, you can call the GetLastError method to see what went wrong. The documentation for that method:

GetLastError

Retrieves the last error generated by the engine.

Syntax

bReturnValue = CalcEngine.GetLastError(ErrorMsg)

Parameters

bReturnValue Boolean/Integer: Returned as TRUE (integer = -1) when the operation is successful, and FALSE (integer = 0) when the operation fails. You can get the last error generated by invoking the GetLastError method.
What happens when you call GetLastError when GetLastError returns false is left as an exercise to the imagination.
flwyd: (Trevor glowing grad macky auditorium)
I've always said that in the 1960s, the boomers had long hair, wild fashions, and radical ideas about freedom and society while the people who programmed computers had crew cuts, crisp shirts, and didn't care too much about society. Today, the boomers have conservative hair cuts, business suits, and don't care too much about society while the people who program computers have long hair, wild fashions, and radical ideas about freedom and society.

Evidence.

I'm working on a hypothesis to explain the correlation between beards and computer programming. I might posit that the same laziness that leads to writing a computer program to solve boring problems also leads to focusing energy on solving interesting problems every day instead of trying to solve the Sysyphusian problem of why hair appeared on our chins the night before. Alternatively, it may be a warming effect: long hair and a beard better insulate our heads, where most of the body's heat loss occurs. And while silicon-based computers work better the cooler they are, neuron-based computers may work better the warmer they are. Or perhaps the beards just give us something to fidget with while we stare at some source code and say "How could a bug get in there?"

goldberg.rb

Monday, October 22nd, 2007 08:57 pm
flwyd: (what would escher do)
Someone should organize a Ruby Goldberg competition in which programmers come up with convoluted-yet-interesting scripts to perform relatively simple tasks.


(Trust nerds to think alike: there's already a Goldberg Ruby on Rails project. But it doesn't look sufficiently absurd.)
flwyd: (java logo)
The type java.lang.Object cannot be resolved. It is indirectly referenced from required .class files.

Software Design: A Meta4

Wednesday, May 16th, 2007 12:45 am
flwyd: (java logo)
Software design is the art of placing rugs about your house in such a way that nobody notices what's been swept underneath them.

Chaos Game Applet

Sunday, April 22nd, 2007 01:52 pm
flwyd: (java logo)
[Chaos Game] I spent most of yesterday and the first part of today writing a Java applet implementation of the Chaos Game. I find that the color schemes help significantly to understand why configurations lead to the patterns they do. The original description (which explains verbally better than I have) just featured monochrome images.

While I write Java code every day at work, most of it is data-focused. Data-focused GUIs (put this field over here, put these buttons in this panel over here) are important and often tricky to get right, but it's been years since I did anything with public void paint(Graphics g). Playing with code which requires no database, no metadata configuration, and no client-server communication was also refreshing.

You'll need at least Java 1.4 to view the applet. I compiled from Eclipse running under Java 1.5 and while I don't think I used any new API methods I didn't have a 1.4 JVM convenient for testing. Let me know if you can't get it to work.
flwyd: (java logo)
Excitement: "I think this project is almost done. If I stay late, I can finish the last couple pieces and commit it so people can test the changes tomorrow morning."

Disappointment: "It's a little later than I wanted to leave, but it's done. I think it's time to commit. Oh, crap. I still haven't done the part I keep ignoring because it's going to be a bunch of annoying work."

++preincrement

Sunday, March 18th, 2007 11:08 pm
flwyd: (mathnet - to cogitate and to solve)
A lot of programming languages, going back to at least C, support preincrement/postincrement operators ++ and --. For instance (in perl, with \n ignored for clarity):
$i = 42
print ++$i

43
print $i++
43
print $i++
44

Explicitly, the expression ++variable changes variable to be variable + 1. The value of the expression is the new value of variable. On the other hand, the expression variable++ changes variable to be one larger, but the value of the expression is the old value of the variable. In most languages, ++variable is equivalent to variable += 1. 1 receives special treatment because of the sheer volume of C code which accesses successive items in an array or increments or decrements a counter.

Ruby is an interesting language. It's got a lot of flexible syntax, borrowed in large part from perl. But in Ruby, everything* is an object and all operations are method calls on an object. Any class can define a + method, so 'book' + 'keeper' == 'bookkeeper' and matrix notation is easy to handle. Classes cannot define a += operator. Instead, ruby treats i += 42 as shorthand for i = i + 42 and l = [1, 2, 3]; l += [4, 5, 6] produces [1, 2, 3, 4, 5, 6]. But a warning to C, C++, Java, and Perl junkies: ++ and -- do not work the same way:
irb(main):001:0> i = 42
=> 42
irb(main):002:0> --i
=> 42
irb(main):003:0> ++i
=> 42
irb(main):004:0> i++
SyntaxError


Why? - and + are unary operators. -42 is equivalent to 0.-42 (that's invoking the "-" method on 0 with 42 as an argument, possibly clearer as 0.-(42)). +foo is equivalent to 0.+(foo). Furthermore, unary operators can be repeated: -(-42) is the same as --42 is the same as 42 (since there are two negatives). ++foo is the same as ++++++++++foo is the same as +(+(foo)) is the same as foo. Furthermore, whitespace is ignored, so while i++ as the last line of a block is a syntax error, the following may surprise you:
irb(main):001:0> 42++
irb(main):001:0* --42
=> 84


I should also note that Python has the same behavior as Ruby (and had it first). In addition, Python lets a class define its own __iadd__ method which responds to += syntax:
>>> l = [1, 2, 3]
>>> l += [4, 5, 6]
>>> l
[1, 2, 3, 4, 5, 6]
>>> l.__iadd__([7, 8, 9])
[1, 2, 3, 4, 5, 6, 7, 8, 9]


I wrote this post in part because Googling ruby "++" returned lots of pages which mention both Ruby and C++. And since ++ doesn't have any particular significance to the language, none of the documentation returned by ruby "++" -"c++" mentioned it. So by mentioning python, ruby, ++, --, plus plus, minus minus, and operator in close succession I hope to aid future confused language converts. Thanks to #ruby-lang for the quick answer.

I should also mention that ++i in these languages is equivalent to the LISP/Scheme (+ (+ i)). Furthermore, in those languages you can define your own implementation of the ++ or -- function. You can even define a variable i and functions ++i, --i, i++, and i--:
> (define i 42)
> (define ++i (lambda () (set! i (+ i 1)) i))
> i
42
> (++i)
43
> (++i)
44


(Un?)fortunately, that function only affects one variable. (++j) would complain that the function ++j doesn't exist.

*: Not quite everything in Ruby is an object or method call. Control structures like if then else are expressions (unlike languages such as C, Java, Perl, and Python), but they are not method calls; you cannot override the if method (unlike functional languages like LISP and Scheme or pure object-oriented languages like Smalltalk and Io).
flwyd: (daemon tux hexley)
This language was developed at the Marin County Center for T'ai Chi, Mellowness and Computer Programming (now defunct), as an alternative to the more intense atmosphere in nearby Silicon Valley.

The center was ideal for programmers who liked to soak in hot tubs while they worked. Unfortunately few programmers could survive there because the center outlawed Pizza and Coca-Cola in favor of Tofu and Perrier.

Many mourn the demise of LAIDBACK because of its reputation as a gentle and non-threatening language since all error messages are in lower case. For example, LAIDBACK responded to syntax errors with the message:
"i hate to bother you, but i just can't relate to that. can you find the time to try it again?"

My Mission Statement

Wednesday, March 7th, 2007 04:24 pm
flwyd: (java logo)
In a meeting to discuss mission-statement type things where people kept mentioning things like "quality" as goals, I stated

"My mission is to write software that kicks ass."

throw null

Thursday, January 18th, 2007 03:45 pm
flwyd: (java logo)

I saw some typo Java code in my CVS update today which called throw null. I wondered just what that would do. null can be cast to any object, so I thought it might get caught by the first catch clause. Alternatively, I thought it might escape all catch clauses (dangerous!). The answer?

	try {
	    throw null;
	} catch (IllegalArgumentException e) {
	    System.err.println("Caught IllegalArgumentException " + e);
	    e.printStackTrace();
	} catch (NullPointerException e) {
	    System.err.println("Caught NullPointerException " + e);
	    e.printStackTrace();
	} catch (Throwable t) {
	    System.err.println("Caught Throwable " + t);
	    t.printStackTrace();
	}

Caught NullPointerException java.lang.NullPointerException
java.lang.NullPointerException
	at TestStuff.main(TestStuff.java:156)

Java (even pre-1.5) automatically creates a NullPointerException if you throw null. It's like very specialized autoboxing.

flwyd: (hexley fork)
At some point, my iTunes library location was incorrectly set to the Music folder in my home folder instead of my external hard drive. [livejournal.com profile] tamheals downloaded several albums, ripped a few, and we bought six songs from the iTunes store. At a later time, the setting was changed to the correct location on the external hard drive and the files from the Music folder were re-added to iTunes and copied to that path. I therefore had two (in some cases three) entries per song for these albums. One evening I went through and moved the Music files to the trash and deleted them from the iTunes list, making sure I could still play them. A few weeks later, Tam emptied the trash. Suddenly, all of the files I'd deleted were marked as missing from iTunes. Somehow (presumably user error) the files were no longer on the external hard drive.

The iTunes Store (unlike Calabash) only lets you download each purchased song once and advises you that you can burn them to CD. Burning a CD with six unconnected songs hadn't seemed like an important move. This is not a feature which benefits the consumer in any way

Fortunately, most of the deleted files are on Tam's iPod. Unfortunately, the iPod file system is obfuscated. Fortunately, there's a mp3info Ruby gem and I've been reading the Ruby Cookbook. I wrote the following script to go through all the mp3 files on the iPod and print the title, artist, album, track, and file path. I then went through the songs marked missing in iTunes and copied the file names into a text file, munging each line into a copy statement.

The script doesn't work on .m4a (AAC) files since mp3info can't handle them. Several minutes of googling finds only references to an MP4Tag ruby library by Miles Egan. Links to that page produce a 404. Archive.org has the old page, but didn't archive the tarball. The site seems to have been hijacked. If I get ambitious I may try to find an AAC specification and parse the files myself, but I think I'll accomplish the task with a list of songs I'm looking for and grepping each .m4a file.

Update, two hours later: Files purchased from the iTunes Store have a .m4p extension (rather than .m4a), so recovering the MIA purchased songs was a simple as ls -l /Volumes/RhiPod/iTunes_Control/Music/*.m4p and comparing the file modification dates with those iTunes remembered for the missing songs. I also found faad2 and installed it through DarwinPorts. faad2 is a decoder for AAC files and the -i command line option prints a lot of information, including metadata. I ran it on all the .m4a files and saved the output to a textfile which I can process with the flip-flop (..) operator.

findmp3s.rb )
flwyd: (java logo)
Save me Edsgar! I just wished I could use a goto statement in Java. My code's primary purpose is to take a bunch of fixed-width data and save it to another file in a tab-delimited format. I decided to add the ability to save the layout. If the layout file already exists, I prompt the user with a Yes/No/Cancel dialog to overwrite. If they cancel, I don't want to write anything (layout or data) and just return from the function. If they say no, I won't write the layout file, but I still need to write the data. If they say yes, or if the file didn't already exist, I write the layout file and then write the data. With a goto, I could break out of my if conditions and just write the data. But without the goto, my options are to set a status flag, write a function to prompt and write the layout, returning a boolean if it was canceled so I can refrain from writing data (probably the best solution), or the following solution: write a one-iteration for loop and break to a label, like so:
Read more... )

Programming Pun

Wednesday, December 13th, 2006 09:32 am
flwyd: (fun characters)
If you're trying to figure out how control escaped from your anonymous function you could say it's "on the lambda."

NaProgWriMo

Tuesday, October 17th, 2006 10:38 pm
flwyd: (mail.app)
I wonder if a program which uses 50,000 identifiers counts for NaNoWriMo.
flwyd: (glowing grad macky auditorium)
If I stay at work until 9:30 listening to Prince and reading the Common Lisp specification, what does that make me?
flwyd: (java logo)
If they wrapped Cleopatra in a rope matrix before the snakebite it would have been death by ASP.NET.

Someone should create an anti-MS framework called Dot Nyet.

Fun Java Facts

Thursday, April 27th, 2006 06:12 pm
flwyd: (dogcow moof!)
Running JVM 1.4.2_08:
System.out.println("1 + --0 = " + new BigDecimal("1").add(new BigDecimal("--0")));
1 + --0 = 1
System.out.println("Int " + new BigDecimal("--00").intValue());
Int -1
System.out.println("Double " + new BigDecimal("--0").doubleValue());
ArrayIndexOutOfBoundsException: -1
System.out.println("BigDecimal " + new BigDecimal("--0").toString());
ArrayIndexOutOfBoundsException: -1
System.out.println("BigDecimal --42 = " + new BigDecimal("--42").toString());
NumberFormatException: Illegal digit
May 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 2025

Most Popular Tags

Expand Cut Tags

No cut tags

Subscribe

RSS Atom
Page generated Friday, June 6th, 2025 09:06 am
Powered by Dreamwidth Studios