addressalign-toparrow-leftarrow-rightbackbellblockcalendarcameraccwcheckchevron-downchevron-leftchevron-rightchevron-small-downchevron-small-leftchevron-small-rightchevron-small-upchevron-upcircle-with-checkcircle-with-crosscircle-with-pluscrossdots-three-verticaleditemptyheartexporteye-with-lineeyefacebookfolderfullheartglobegmailgooglegroupsimageimagesinstagramlinklocation-pinm-swarmSearchmailmessagesminusmoremuplabelShape 3 + Rectangle 1outlookpersonJoin Group on CardStartprice-ribbonImported LayersImported LayersImported Layersshieldstartickettrashtriangle-downtriangle-uptwitteruseryahoo

Austin Clojure Meetup Message Board › Clojure Cup ideas

Clojure Cup ideas

Norman R.
normanrichards
Austin, TX
Post #: 41
Here's a summary of the ideas we tossed around at the hack night tonight:



  • Infinite monkeys - extend the pi-game idea to allow arbitrary letters. points are awarded for forming words that appear in the works of shakespeare.
  • Weather map - take public weather data and generate weather maps in the browser from it
  • Core Wars - implement a core wars simulator in clojurescript, with a fun visualizer on the core during battles. If possible, consider ways to make redcode more lispy


If I missed anything, please post. If people have other ideas, add them below. If we are lucky, we may plebe able to field more than one team, so the more quality ideas the better. Good ideas that we don't use for the Clojure Cup could also become group projects, so now is the time to propose ideas.
James
user 7494696
Austin, TX
Post #: 1
I really like the idea of just doing a lisp wars. Red code and core wars is great for what they are, but it isn't exactly creative or original. And it definitely isn't lispy.

Hopefully I can do a better job tonight of expressing what I thought up when Sam tossed the idea out (or does someone else deserve the credit?) I know I'd moved into complete geek mode when I tried to describe it last night, so I was pretty much totally incoherent.

Von Neumann machines are really practical, physical ways of building something that resembles a Turing machine in the real world. It's been a while since I paid any attention to them, but it seems like the machines in core wars are somewhere in between the two. Just glancing at the instruction set, I didn't
get the impression that it's Turing complete, but I could be totally wrong about that.

The main points seem to be that that VM has a small circular address space, 1 instruction pointer per thread, a simple scheduler, and a instruction set that's been honed for battle.

Anyway. McCarthy's original lisp is something that's always struck me as a very interesting alternative to Turing machines.

We've wound up running them on von Neuman machines, but that's mostly a historical accident (as I understand things).

If we were going to be ambitious, we could try to emulate a real lisp machine. I suspect that would be way outside the scope of what we could accomplish in just 48 hours. Especially since we should probably plan on spending most of the time writing warriors, if we want to tackle this.

I can think of two or 3 directions that seem like they'd work.

The most obvious seems to build trees of cons cells in that same kind of address space. Each cons cell is a pair of pointers: one to a car, the other the cdr. Let programmers update them arbitrarily.

Or maybe we just have an arbitrary flat address space with no distinctions. An address deference could pull back 2 words: the first is the car, the second the cdr.

Or maybe we should think of emulating the original (was it an IBM 720?) with its 36-bit address space.

The actual byte code seems more interesting than memory layout questions. Should we go with special meaningful numeric values? Or just use named symbols (which sounds easier all around)? If you try to eval a cons cell with a symbol that isn't a function/special form in the car, your program loses.

If we go with numeric byte codes, we could obviously go with special values for McCarthy's original special forms. We need something else to let us read/write arbitrary addresses (although I think we should keep redcode's idea that all addresses are relative to the current IP), like setq or aref. I think it would be better to skip all the fancy addressing modes they've added, but that's mainly because it seems like a good simplification to trim back a potentially nasty time sink. (And it's totally not lisp-like).

At the end of a top-level form, you advance the IP. Or you jumped. It might be interesting to implement function calls and returns, but that might also be a stupid waste of time [actually, the more I think about this, the more it seems like a requirement, since we're working in at least a vaguely functional language]. Obviously, the bigger your footprint, the more vulnerable your program is. Then again, adding a stack pointer and giving opponents a chance to corrupt that, followed by inserting a return into your code...would probably not make a very fun game. Alternatively, we could implement continuations, but...that seems like a pretty bad idea. [Maybe give each thread its own stack space? Or each program, and divide that among its threads?]

So, what does this look like in practical terms? I don't really know, but the first notes I jotted down when I got home were really just breaking up something really simple into cons cells.

I didn't get that experience in college, so bear with me.

(let ((a 0x40) (b 'halt) (c 4))
(setq a b)
(jmp c))

translates into something more or less like

(cons 'let (cons (cons (cons 'a (cons 0x40 ())) (cons 'b (cons 'halt ()))
(cons c (cons 4 ())))
(cons (cons 'setq (cons 'a (cons 'b ())))
(cons 'jmp (cons 'c ())))))

That's obviously far too verbose to be useful, but I was really just brainstorming. It's really just a possible sample...you'd obviously need something set up to jump to.

Let's say we have 2 warriors that are really a series of top-level forms. Load them both into memory at some more-or-less random location. If they don't both fit, the smaller one wins.

I think it might be a neat feature to let them specify arbitrary memory addresses (relative to start) for placing initial code. That may be too much of an advantage/complication.

After that, we pretty much just take the core wars model. We have one environment/IP for each program. If we have time, multi-threading would be awesome. Pick one program randomly to go first. Then take turns
running eval on individual cons cells. (Yes, picking which cons cell to execute next is interesting).

There are tons of examples of implementing McCarthy's original paper in pretty much any language you could want all over the internet. I don't know if there are any that set up this sort of use case (bouncing back and forth between execution environments), and I seriously doubt there are any that cover the sorts of additions we'd need, but the foundations are laid down pretty well.

That leaves all sorts of unanswered questions. Like introducing named variables or arbitrary symbols. Do the programs occupy the same namespace? What happens if you try to execute a function the other guy defined? Quote gets weird enough...do we want to allow eval? (Yes, I've been reading Lisp in Small Pieces). What does "jump 3" actually mean? Jump ahead 3 words in memory? 3 top-level cons cells?

Aside from this, we'd need a way to load warriors into memory, some sort of visualization, and whatever other bells and whistles come to mind. Along with, of course, warriors.

Add in a REPL and let programmers really battle it out (rather than just kicking off programs and letting them compete) and I think we've really moved it into the Land of Lisp. Then again, humans are way too slow for this, and I don't see us adding that by the deadline. But it seems like a neat idea.

Other options that were suggested include things like our own redcode emulator or doing something like building warriors for the real game using genetic algorithms. They're both more realistic, but I think the other suggestions have better chances of winning.

At least, that's my initial take.
Norman R.
normanrichards
Austin, TX
Post #: 42
(edit - sorry, it seems the forums here eat code and don't preserve spacing. If the code isn't clear, I can make a gist)

I spent an hour at lunch today trying to make it work, but I just can't find a way. Maybe we need to get everyone together at a whiteboard and try to hash things out?

A couple thoughts - first, we should keep in mind that it has to be possible to write programs with interesting behaviors. (moving program segments around, jumping to new locations, etc...) So, if we were to do something other than traditional core wars, we should keep in mind the question of what kinds of interesting behaviors are enabled.

Second, I think a Lisp bytecode would inherently be stack-based. It's my understanding that this is how the lisp processors worked. To be sure, you could compile that to something register based, but at some point you'd lose anything even resembling the original lisp, so there'd be no real advantage. I made a little forward progress imagining this as more of lambda calculus style where the language only has function invocations and single argument (curried) functions. That definitely eliminates a lot of the cons-wrangling...

We could (and should) pursue the lisp/stack-based adaption of core wars, but let me propose something else that might keep with the core wars tradition but be less offensive to out lisp-sensibilities. My first idea would be that we do a simple translation of a core wars program to a clojure/data syntax. So, here's a core wars program:

ADD #10, #-1
MOV 2, @-1
JMP -2, 0
DAT #33, #33

The naive translation to clojure data would be:

(redcode
(add #10 #-1)
(move 2 @-1)
(jump -2 0)
(data #33 #33))

Where redcode is a macro that emits the actual byte sequence that would be loaded into memory. That's not much of a step forward, but it does give us the full power and semantics of redcode in a place where we can use clojure macros and do other fun things. For example, that jump -2 is a simple loop:

(redcode
(repeat
(add #10 #-1)
(move 2 @-1)) ;; repeat macro inserts the jmp -2
(data #33))

Now the the move 2 @-1 doesn't make sense because we can't really see that it is 2 statements ahead. We could write it as (move 1 @-1) and assume the system will translate that as move 2 when it inserts the data line, but we could also add a label:

(redcode
(repeat
(add #10 #-1)
(move wall @-1)
(label wall
(data #33))))

This could take on some other syntax like an assembler label, but I think we're trying to keep this more lispy. We could also replace the @-1 with a label:

(redcode
(repeat
(label x
(add #10 #-1)
(move wall @x)))
(label wall
(data #33 #33)))


Obviously this code would be easier to read if the add weren't acting as both a memory location AND an add operator. So, perhaps this slightly larger program would be better: (this program has different, but similar behavior - I don't have a corewars interpretter in front of me to test it)

(redcode
(repeat
(add #10 ptr)
(move wall @ptr))
(label ptr
(data #-1)
(label wall
(data #33)))


Anyway - you might still be looking at this and thinking it's not terribly lispy, but hopefully this work suggests that we can build interesting lispy abstractions on top of redcode without needing to invent a whole new instruction set and game.


James
user 7494696
Austin, TX
Post #: 2
I think that getting together at a whiteboard is probably a great idea.

My version this idea is definitely no better than half-baked (at best).

The stack/register part of the discussion definitely gets muddy. My vision is totally clouded from the [very limited] x86 asm that I've done. Along with the [extremely] little I know about VMs in general.

Doing a redcode-generator in lisp is definitely an option, of course. Or implementing a "real" codewars VM. I could be missing something glaringly obvious about the possibilities. This is where conversation is valuable. From my perspective, that seems like generating code for another language via DSL. Why not do, say, something to generate WordPress plugins?

(If that sounds flippant or dismissive, I definitely didn't mean it that way. I'm *seriously* looking at generating scala code for Play at work, and I kind of desperately need to get another tech blog up and running again in my spare time. Considering my lack of spare time, that pretty much means WP...although I've spent the past 3 weeks-ish dabbling around with plone again).

The clojure blog market is wide open and begging to be tapped. It was mentioned on the mailing list a while back, but I haven't heard anything since. It's not like this is a difficult problem...
James
user 7494696
Austin, TX
Post #: 3
Just for the record:

My second vote is for the "infinite Shakespeare monkeys". It seems like a great way to completely and totally abuse network resources.

No, really, this is valid (and not a bad idea!)

Let's say you get 1000 connections (I'm an optimist) and the average monkey hits 4 keys a second.
m
That isn't reasonable.
e.dh.dpeudhfwujjuujepujmhujujuj
Random sampling of 1 gentle monkey (I *like* my keyboard...mostly). That was 31 keystrokes in somewhere around 5 seconds.

So, from that hypothetical scenario, that comes out to somewhere around 6000 keystrokes a second (conservatively).

Depending on how the web interaction is implemented, that kind of traffic could cause serious issues for a lot of servers.

Add in a hacker or two who's set up something like http-kit clients on 8 different cores to spew out random POSTs as fast as possible, and I think this looks really interesting.

Then again, I also suspect it's getting way beyond the 48 hour scope.
Norman R.
normanrichards
Austin, TX
Post #: 43
Depending on the number of people interested, we may be able to field two teams, so there's still time to formulate new ideas and add them to the list, so please do develop that idea a bit. We can discuss it at the next meeting, unless we get together sooner.

I like inifinite monkeys because it's clearly doable in the time frame proposed, and it's got a little bit of a fun idea. I like core wars because, because we can also easily finish it in the time available, assuming we don't go wild trying invent something new. The tasks split up really well, and it's got the geek hook along with some good visualization potential. The other ideas so far need to be developed a bit more before we can really evaluate them.

Back to core wars. I think a redcode DSL would work extremely well. I talked with Sam a bit last night and it was very clear that in the spirit of what I put above we could add a basic IF, LOOP and vars to the language fairly trivially, and with a little time we could even add something resembling a function call. The looking at the proposed code, it starts to look very lisp-like and really adds some clarity and structure to things as you'd expect a higher level language to do. It wouldn't be Clojure/LISP but it would be a pretty fine example of a Clojure DSL with higher level constructs.









Norman R.
normanrichards
Austin, TX
Post #: 44
Here's another fun idea. It would be really easy and would make a fun app if it turns out we have a team that has fewer people or we can't make the time commitment for the full weekend.

Rich Hickey Facts

This would be in the style of Chuck Norris Facts or Bruce Schnier Facts. Our facts could be like "In Clojure, values aren't immutable. Their just too afraid of Rich to change". Or "Rich Hickey can eval (last (range))". Ok, well, maybe I'm not that funny, but I'm sure with some group effort we can collect some fun facts. The app could start simple - just presenting facts. It could be made more complex by adding suggested facts, voting, etc... But the basic idea couple be implemented in an afternoon

The basic advantages of this idea are that it's easy and has places for less experienced Clojurists to contribute. It also has perhaps the best hook of all of our ideas. It wouldn't win, but it would get noticed/mentioned. And, we could actually leave the site up later to promote the groups. We could probably even toss some google adwords on it and fund infinite pizzas for the meetings...

James
user 7494696
Austin, TX
Post #: 4
Another couple of ideas that came to mind:

1) Stu Halloway mentioned a "better REPL" when we met him at lunch. Something that gathers facts and statistics, looks up issues in some central database ("I see that you've tried to do x 3 times now and keep getting this exception...maybe you really meant to try y..."). It sounded vaguely like Clippy for newbs. It really sounds like a much longer commitment than this, but it might be worth throwing together some sort of prototype.

2) The mailing list seems to go back and forth about whether a clojure debugger is a worthwhile endeavor. It *definitely* isn't a weekend project, and I don't see much point to trying to do a web-based one. But (coming from a common lisp experience) my first reaction to clojure exceptions was "Wait...why on earth did my program exit rather than sending me to a debugger?"

It definitely would be interesting to see how a higher-level DSL could compete in core wars.
James
user 7494696
Austin, TX
Post #: 5
Just a thought about the "Rich Hickey's Brain" idea, based on an IRC conversation I ran across recently: how about something like fortune that produces something about some random clojure library (rated by the community)?

They were wanting something to remind them of all the libraries from technomancy and ztellman that they don't want to rewrite but can't manage to keep up with.
James
user 7494696
Austin, TX
Post #: 6
Ooh...clojure-ish version of corewars:

There are actually n different cores, sharing the same memory space. Execution is as random as we can make seem even vaguely fair. Now the game totally changes to how good you are at protecting your state...except that it's a dumb idea. I've spent too much time lately thinking about the uses for thread-local bindings.

If you can trust your address space, that destroys the entire point of the game. If you can't...that destroys most of the point to clojure. So I'm starting to agree that this idea seems like a dead end.
Powered by mvnForum

Our Sponsors

People in this
Meetup are also in:

Sign up

Meetup members, Log in

By clicking "Sign up" or "Sign up using Facebook", you confirm that you accept our Terms of Service & Privacy Policy