open science enthusiast ~ software developer ~ under the sea code monkey
439 stories

Toy train meets cold, unfeeling robot arm

1 Comment and 3 Shares

Read the whole story
4 days ago
reminded of Iron Council
Share this story

By: Hicksu

1 Share
Building on ALSweigart's (whose presence I miss at Noisebridge) comment a little. We still use consensus at Noisebridge, but during the period ALSweigart is describing (2013-2014) we ran into serious problems with consensus being overused and used specifically to stop people from improving the space. Before this time, there was an sense in the community of what topics or proposals were appropriate to run through consensus and which weren't. Then the process got overrun by people who found they could use it to paralyze discussions at Noisebridge, so that they could keep living in the space and even stealing from it. We eventually closed the space for a while to break that behavior. This closure was not done via a broad consensus, but by a group of members and long time regulars that believed that shutting down and fixing up the place was a worthwhile last effort to try to restore Noisebridge as a functioning Hackerspace. Since that time, most of the improvements and progress in making the place better and safer for people to work in have been done without (formal meeting discussion type) consensus, and instead by various persons and groups just doing things; which is the process thru which most things were expected to be done in the space, since its founding, anyway. I think that Noisebridge's consensus problems stemmed from realizing too late that it was being overused/misused for the wrong things. The space has been operating much better since, but at the same time we have only had maybe a few consensus related discussions during the meetings since. So I suppose Consensus at Noisebridge seems to work best when it is rarely used. It remains to be seen if we have really learned our lessons regarding our Consensus process, but we have addressed some of the other issues that led to the closure in 2014. We definitely didn't have or use the methods and tools that Orlop outlines above. (great comment)
Read the whole story
16 days ago
Share this story

By: Frowner

1 Share
Also, before we're like "consensus sucks and allows bullying and stymies progress", it's worth noting that many indigenous societies use or have used consensus decision making. Consensus works in some applications, and what's more, no decision-making system really works to preserve the group and forward its aims if the group culture is toxic. Some years ago, I took a really good "train the trainer" training (!!!!) through Training for Change. Probably the most important thing I learned from it was the idea that any group process requires "building the container" - creating, whether for a few hours or for a long-lasting group, a sense of groupness that "contains" what happens in the group. People tend to think that "building the container" is a waste of time, or else they do it badly - that's what all those "Hi my name is Clelia and if I were ice cream I'd be peppermint" group go-round introductions are supposed to do and don't. You need to devote longer than you think you do to introducing people to each other and building appropriate social bonds. For a one-time, short term thing, you only need to create weak and simple bonds, so a few minutes spend on a small group activity or some other structured introduction/interaction are fine. The longer-term and more intensive the interaction will be, the more time and care you need to devote to the container. A "container" creates a sense of group norms (is this a group where we say 'fuck' or just 'damn'?). It creates a sense of group identity ('we are all middle managers!!!'; 'we are all theosophists!!!'). It clarifies and improves purpose. It gives people some sense of who the others in the room are and what their concerns are. IME, it also gives people who like to chat a little time to run their mouths, and people who are shy a little time to warm up. A "container" should match the nature and purpose of the group - you don't push people to get really emotionally intimate, and you don't push people to share what they don't want to share or do things that make them uncomfortable - there are no trust falls in container building. And again, we're looking at a process that needs to match the length and nature of the project. If you build your container well and maintain it over many meetings, you are far more likely to naturally determine a good way of making decisions, less likely to bully and more likely to succeed with the decision-making process that you choose. Most of the groups that I've seen founder on the rocks of consensus had, basically, really shitty containers for group work - either they didn't have one, or the group itself always functioned in a bully-led/charismatic-led way, or the group itself always-already ignored the concerns of marginalized people.
Read the whole story
16 days ago
Share this story

By: Orlop

1 Share
I'm a Quaker, and we could tell a lot of stories about both the triumphs and tragedies of seeking unity as a body. One of the things that makes it work better in a Quaker setting than I've experienced in other places (like collectively-run feminist and lesbian bodies back in the 80s and 90s) is that there is a strong shared value placed on the process—which is to say, we really deeply believe that it is possible to find a shared perspective and that how we get to a decision is at least as important as the decision itself. So, for instance, there is a Quaker practice of minuting when unity can't be found—we accept that sometimes it's just not possible. It's rare, but some of the most powerful Quaker business meetings I've been at have ended in a painful shared recognition that we couldn't all come together on an issue. Also, we do this unity shit all the fucking time. It's how we make every decision in our monthly meetings (the odd Quaker name for the body that meets every week for worship and meets for business meeting once a month, hence the name); in committee meetings; at Quarterly and Yearly meetings. Our kids start having business meetings "in the manner of Friends" as, like, kindergartners. As a result we have vast experience in every kind of outcome: someone strongly disagrees and blocks a decision; someone strongly disagrees and, realizing that they are out of step with the body as a whole, "steps aside"; easy unity; and hard unity that comes only after weeks, months, or years of working on an issue. We have meetings called "threshing meetings" where we get together over a difficult decision with no intention of making a decision, but only to listen to each other. We are deeply trained not to speak more than once on an issue unless we are very strongly led to do so; we allow silence between speakers; we have no taboo against changing one's mind—it is expected that listening deeply to the insights and experiences of others will change hearts and minds, and when someone says, "I came into this meeting feeling strongly that X, but after listening to you all, I am now comfortable proceeding with Y," we accept that as part of the process. We rarely dig in our heels or defend an initial position (if someone is regularly doing this, they are not in order and will usually be called out on it). In addition, every meeting is clerked. It has one person (sometimes two sharing the role) whose job is to facilitate things, but more deeply to listen and try to hear an emerging unity. You'll hear a clerk say, "I'd like to propose a minute," and then they will sum up what we call the "sense of the meeting," and surprisingly often, even when we didn't think we were coming together, they will have found the place where we agree. If a meeting is getting contentious, the clerk will often call for silence. Hands are up all over the room, everybody wants to throw in their two cents, and the clerk will say, "Let's settling into some silent worship," and after a couple of minutes, when you can feel the energy of the room has come down a bit, they'll say, "OK. Now, I'd like to hear from people who haven't spoken before, or who have points that haven't been made before, or who feel very strongly about being heard." Usually 9 out of 10 of those hands won't go back up, because on reflection a person has cooled off, or realized they were just repeating someone else. We also say, "This Friend speaks my mind" when we strongly agree with someone. That way you don't have to stand up and spend five minutes repeating what that person said. A clear can ask someone if they're willing to stand aside, if it's clear they're alone outside unity. This is why we talk about the "sense of the meeting" and not "universal agreement." If someone does step aside, this is minuted. When my meeting was thinking of building a meetinghouse after decades of meeting in rented spaces, one woman who had belonged to a meeting with a meetinghouse really opposed the idea. She felt, based on her experience on the Building and Grounds committee there, that a meeting that owns a building can find its energy and purpose diverted to supporting the building. Finally, when it had become clear that the meeting as a whole was ready to buy property, she stood up and said, "You all know I oppose this, and that hasn't changed. I do feel, however, that my concerns have been heard, and I recognize that I am out of step. I'd like to stand aside on this decision." This meant that we didn't have to persuade her to support building a meetinghouse; she thought we'd listened and taken her concerns seriously, and she was willing to let it go. We take clerking really seriously. We study how to do it; there are workshops and books and retreats on how to do it well. Everybody clerks at some point. Every committee has a clerk; even a casual one-off meeting to discuss, oh, what we're serving at the annual picnic will start by choosing someone to clerk the meeting. In this way we build experience, and we also discover who has particular gifts at clerking. A good clerk is a joy to behold; a weak one is a burden to be borne until their term ends. It is common in Quaker organizations to limit terms of service on committees and as clerks, so as to give everyone experience and also to avoid individuals becoming entrenched. I have a friend who has been holding a monthly meeting for worship for a particular purpose in his home every months for, oh, twenty years? He keeps it going; he hosts it; he provides food and tea every month. But he doesn't clerk it. At the beginning of every month's meeting, somebody volunteers. Of course, we are also very aware that every contentious decision eventually gets made in part because some people leave. Same-sex marriage, for instance, has been supported by many liberal Quaker meetings for decades. When my partner and I, then a same-sex couple, attended our first meeting at our local Friends meeting back in 1994 or so, somebody came up to us after the meeting to tell us that they did same-sex union ceremonies. They'd minuted their support not long before, and hadn't had a chance to actually do one yet. (The meeting has done quite a few by now; but not one for me and my partner, although we are still together.) Every meeting that minuted support for same-sex marriage lost people over it. Sometimes unity is reached in part because the people who are not unity go away, leaving behind a bunch of people who agree with each other. Some of the more conservative branches of Quakerism are experiencing schisms, or at risk of them, over same-sex marriage. Heck, over whether it's OK to be gay at all. This is very painful, but hard to avoid. We've also seen meetings go to hell over the most minor issues: the color of the new carpet, say. A friend of mine recently visited a meeting while traveling, and reported to me with an eyeroll that, in this time of political strife and the deep need for people to stand up for human rights and help the vulnerable, they were embroiled in a lengthy and contentious conflict over whether to install air conditioning in their meeting house. We also can end up wasting a lot of time on trivial issues. Until you've sat in a poorly-clerked meeting of 50 people, all having their say on where the commas should go in a minute or epistle, while the first truly beautiful spring day of the year fades into twilight outside the window, you haven't really experienced Quakerism. At its best, Quaker process is transcendent, holy, a powerful force for human connection and good in the world. At its worst, you spend the best years of your life getting way too invested in whether the windows in the social hall have blinds or curtains. I talked about a person not in unity standing aside. Although it's rare, Quaker process also allows for a meeting that is otherwise unified to make a decision even if Friend Decision-Blocker won't stand aside. I think I've seen this happen once in all my years of Quakering; it's a less-than-ideal outcome and always feels a bit like we've failed. But there are times when time is tight or action has to be taken quickly, and at those times "sense of the meeting" doesn't necessarily mean "everybody agrees 100%." Yours in the Light, as we Quakers say, Friend Orlop.
Read the whole story
16 days ago
Share this story

Hexing the technical interview

3 Comments and 5 Shares

Long ago, on Svalbard, when you were a young witch of forty-three, your mother took your unscarred wrists in her hands, and spoke:

Vidrun, born of the sea-wind through the spruce
Vidrun, green-tinged offshoot of my bough, joy and burden of my life
Vidrun, fierce and clever, may our clan’s wisdom be yours:

Never read Hacker News

But Hacker News has read of you, in their snicker-slithing sussurential warrens, and word has spread, which is why the young man offering you a smörgåsbord of microkitchen offerings looks mildly suspicious already. He whisks you into a glass shoebox of a conference room, which somehow manages to be claustrophobic despite the open sightlines. You make a mental note to avoid this conference room in the future, but reassure the room it’s nothing personal.

“So my name is Tim, and I’ll be your first interviewer today…” Tim is making every effort to be cheery. His ears stick out a bit, and in his dark-brown hoodie and cream shirt, perched expectantly at the table, he resembles something of a pine marten. You like pine martens, and therefore Tim as well.

“Before we get started, is there… anything I can tell you about the company?”

You would like to ask what kind of call Tim would make, were he guarding his cache of eggs and nuts against another marten–but instead, you just giggle to yourself, lean your sprig of cloud-pine against the corner, and settle comfortably to the floor. Tim leans in to get a clearer view of where you’ve gone. Definitely, you think to yourself.

“So, erm… Perhaps you could tell me a bit about your background?”

He hasn’t read your resume. No man can.

“In the winter,” you begin, “above the ice-locked fjørds, lies a creek, ash-white with the ghosts of glaciers–”

“You know what?” He interrupts. It was a beautiful story, but perhaps you can tell it later. “How about we do a little programming together? Just a basic exercise so I can get a sense of how you think.”

“That sounds nice, Tim.”

“OK, great.” Tim seems reassured to be back on track. “So let’s open up an editor. Would you… would you like to have a seat?”

“Come!” You pat the ground next to you. “It is safer this way.” Tim stares at the parentheses of salt with disbelief, shakes his head, and reluctantly sits by your side.

Tim retells an old riddle, though he does not know its origins, and has the words wrong. A group of travelers are lost in the woods, upon a winding mountain path, and worry that they have been traveling in circles. They must know: does their path lead to freedom? Or constrain them to wander forever in the wilderness?

Tradition sets down that the group must split: the fastest runner forges on ahead, while the rest continue slowly. If the runner ever catches them, the trail must loop back on itself.

“So we should start with a linked list?” You smile reassuringly.

“Yes,” Tim says, “but… um… just a regular linked list, please. I know you’re up on, well, functional programming, but we’re a more pragmatic shop here. Building real software. We want something practical.”

“Yes, of course,” you assent. “Practical. Got it.” One of your spiders–you can’t tell which–is picking its way carefully up Tim’s hoodie, and you scoop it up before typing.

(ns cycle-detector.core (:require [ :as io]) (:import ( DataOutputStream ByteArrayOutputStream)))

“We’re, uh, we’re not doing IO here. Just an in-memory list.”

Agree politely, but delete nothing. Never apologize for who you are.

; A simple mutable linked list (deftype MutableLinkedList [value next] clojure.lang.Seqable (seq [_] (lazy-seq (cons value (seq @next))))) (defn node [value] (MutableLinkedList. value (atom nil))) (defn link! [node next] (reset! (.next node) next) next)

“That’s… not what I was expecting.” Tim says. “No, no, it’s good! Straightforward and simple. I was just, you know, they said on the internet that you were…” He trails off, and looks to you apologetically.

Smile disarmingly and shake your wrists free of your wool shift. Then clap your hands, place them firmly upon the disk, and open a portal to the underworld.

(gen-class :name cycle_detector.core.ArbClassLoader :extends ClassLoader :state state :init class-loader-init :constructors {[ClassLoader String bytes] [ClassLoader]} :exposes-methods {defineClass superDefineClass resolveClass superResolveClass} :prefix "-" :main false)

“I’m sorry,” Tim comments over your shoulder. “I’m not really a Clojure expert. What’s this for?”

“Just boilerplate. Don’t worry about it.” Tim appears, if anything, more worried now. “We do this all the time.”

(defn -class-loader-init [^ClassLoader class-loader ^String class-name ^bytes bytecode] [[class-loader] {:class-name class-name :bytecode bytecode}]) (defn -loadClass ([this ^String class-name] (-loadClass this class-name true)) ([this ^String class-name resolve?] (if (= class-name (:class-name (.state this))) (let [bytecode (:bytecode (.state this)) c (.superDefineClass this class-name bytecode (int 0) (int (alength bytecode)))] (when resolve? (.superResolveClass this c)) c) (.loadClass (.getParent this) class-name)))) (defn class-loader [^String class-name ^bytes bytecode] (cycle_detector.core.ArbClassLoader. (.getClassLoader MutableLinkedList) class-name bytecode))

The color has begun to drain from Tim’s face. Perhaps winter has come, and his coat is changing.

(defn run-bytecode [bytecode class-name method-name signature & args] (-> class-name (class-loader bytecode) (.loadClass class-name) (.getMethod method-name (into-array Class signature)) (.invoke nil (object-array args))))

“Clojure is a dynamic language,” you explain helpfully. “So when we call back and forth with Java classes, there’s usually some reflection going on.”

“It looks like you’ve… built a classloader specifically to return a single byte array for a particular class? Is that… is that normal?”

“Yes,” you insist, eyes flashing dangerously.

“Why can’t you just write the algorithm in Clojure?”

“Performance,” You explain, wholly earnest. “Since cycle checking is going to be a tight inner loop, we don’t want to write it in such a high-level language.”

“O–Okay.” Tim stutters. “So you’re going to write the cycle detector in Java then? And call it from Clojure?”

“Something like that.”

(def racer (->> [0xca 0xfe 0xba 0xbe

“What are these?”

“Magic numbers.” You are, after all, a witch. “Every class begins with a babe, in a cafe.”


“You know, a beautiful man–the kind like from the movies–relaxing in the afternoon by the promenade. He has his kaffe, and his orange glasses gleam in the sun, and perhaps some other nice men are jogging by. If they are lucky, perhaps he will lock eyes with one of the joggers, and they will smile, and find a brick-lined alleyway together. His lips press upon the other man’s skin, and he feels the heat of the sun infused there…”

“Excuse me?”

If you were to be honest, you’ve never understood SUN’s rationale for the story, or why the Java Virtual Machine specification, normally so prosaic, lapses into lustful rhapsody for so many stanzas in section 4.1.

0x00 0x00 ; Minor 0x00 0x31 ; Major

“We’re using version 49 because it doesn’t require stack maps, which keeps things simple. Now we need the number of constants.

Remember the future. This is a common trick for protocol wizards, many of whom live as Merlin did, writing constants and buffer sizes before (after) having written (unwritten) the buffers themselves. Recall that 22 sufficed then. Write that down.

0x00 0x17 ; 22 constants

"I’m sorry,” Tim blinks. “But isn’t 0x17 decimal 23, not 22?”

“Og én,” you recite, sing-song, “Til javanissen!”

“Beg pardon?”

“The javanisse. Surely you have heard of him! He is a small, magical man–something like a gnome–who inhabits every JVM. If you do not set out an extra constant for him, he can cause segfaults. But keep the javanisse happy, and your mutices will be fair.” It is a story from your childhood. You remember your mother, chanting offsets as she stirred the stew. “To byter for bufferen anvise / og ekstra én til javanisse.” It is a happy memory, and you lose yourself in it until Tim clears his throat.

“Ah yes. Constants. We’ll need our superclass, Object, of course. Ordinarily I’d use an existing class to save weight, but we’re only dealing with interfaces here so Object it is. And a class for ourself, I suppose.”

0x01 0x00 0x10 ; 1: A UTF-8 string of 16 bytes (.getBytes "java/lang/Object") 0x07 0x00 0x01 ; 2: The Object class 0x01 0x00 0x19 ; 3: UTF-8 string of 23 bytes (.getBytes "cycle_detector/core/Racer") 0x07 0x00 0x03 ; 4: Our class

We’ll take an Iterable, and call .iterator(), which means we need:

0x01 0x00 0x12 ; 5: UTF-8 string of 16 bytes (.getBytes "java/lang/Iterable") 0x07 0x00 0x05 ; 6: Iterable 0x01 0x00 0x08 ; 7: UTF-8 string of 8 bytes (.getBytes "iterator") 0x01 0x00 0x16 ; 8: UTF-8 string of 22 bytes (.getBytes "()Ljava/util/Iterator;") 0x0c 0x00 0x07 0x00 0x08 ; 9: Name and type info (7, 8) 0x0b 0x00 0x06 0x00 0x09 ; 10: Interface methodref for Iterable.iterator()

“And with that iterator, we’ll need hasNext and Next()…” The bytes are coming faster now. This is so much better than Old West Norse hexography, where both odd and even digits shared the same rune.

0x01 0x00 0x12 ; 11: UTF-8 string of 18 bytes (.getBytes "java/util/Iterator") 0x07 0x00 0x0b ; 12: Iterator 0x01 0x00 0x07 ; 13: UTF-8 string of 7 bytes (.getBytes "hasNext") 0x01 0x00 0x03 ; 14: UTF-8 string of 3 bytes (.getBytes "()Z") 0x0c 0x00 0x0d 0x00 0x0e ; 15: Name and type info for .hasNext() 0x0b 0x00 0x0c 0x00 0x0f ; 16: Interface methodref: Iterator.hasNext() 0x01 0x00 0x04 ; 17: UTF-8 string of 4 bytes (.getBytes "next") 0x01 0x00 0x14 ; 18: UTF-8 string of 20 bytes (.getBytes "()Ljava/lang/Object;") 0x0c 0x00 0x11 0x00 0x12 ; 19: Name and type info for .next() 0x0b 0x00 0x0c 0x00 0x13 ; 20:

Tim has gone silent.

“Now you’d think,” you mutter, “that code would be a common thing to put in a class, and therefore it might have a dedicated byte tag–but instead, we have to put the word "Code” in every class and use it to identify our code attributes.

0x01 0x00 0x04 ; 21: UTF-8 string of 4 bytes (.getBytes "Code") ; String for code attributes

Finally, our signature. Take an Iterable, and return a boolean.

0x01 0x00 0x17 ; 22: UTF-8 string of 23 bytes (.getBytes "(Ljava/lang/Iterable;)Z") ; Our arg signature

“Now then.” Crack your knuckles, and inscribe the ancient sigils.

0x00 0x21 ; Flags: public & super 0x00 0x04 ; Our class 0x00 0x02 ; Our superclass (Object) 0x00 0x00 ; No interfaces 0x00 0x00 ; No fields 0x00 0x01 ; One method

Every young witch in your clan was required to memorize these bytes. Such pride, you felt, when you first incanted a class without the training wheels of javac. Our method begins:

0x00 0x09 ; Flags: public & static 0x00 0x15 ; Method name (21, "Code")

“Method names start with lowercase letters,” Tim asserts. His voice rises like a question.

“Only by convention. Almost any string will do, and we already have this one in the constant pool.”

0x00 0x16 ; Method signature (22) 0x00 0x01 ; One attribute ; Method attributes 0x00 0x15 ; Attribute name (21, "Code") 0x00 0x00 0x00 0x48 ; + 2 2 4 bytecode-length 2 0 2 attribute-len 0x00 0x02 ; Maximum stack 0x00 0x04 ; Number of local variables

“Wait, wait, hold on.” Tim has siezed upon a piece of flotsam in the storm. “Only four variable slots? For arguments plus locals?”

“Og tre til javanissen!” You remind him. He sputters while you try to remember how many instructions you’ll have written.

0x00 0x00 0x00 0x3c ; Size of bytecode

Your method begins by creating a pair of iterators from a single Iterable argument.

0x2a ; aload_0 (take arg) 0xb9 ; invokeinterface 0x00 0x0a ; .iterator() 0x01 ; 1 arg 0x00 ; unused 0x4d ; astore_1 (store iterator) 0x2a ; aload_0 (take arg) 0xb9 ; invokeinterface 0x00 0x0a ; .iterator() 0x01 ; 1 arg 0x00 ; unused 0x4e ; astore_0 (store iterator)

“Did you mean astore_2?” Tim asks, trying to be helpful. “Variable 0 holds our first argument, right?”

“It did.” You agree. “But we won’t be needing it again.”

“But… those aren’t even the same type. That’s… that’s illegal.”

“If it were meant to be illegal,” you remind him sagely, “Sun Microsystems would have made it unrepresentable.”

One will be the fast iterator. Her name is Jorunn, and her legs are strong from years of skiing. She flies forward with powerful strokes.

0x2d ; aload_1 take fast iterator 0xb9 ; invokeinterface 0x00 0x10 ; hasnext 0x01 ; 1 arg 0x00 ; unused 0x9a ; ifne 0x00 0x05 ; jump ahead 3 if we have a next element 0x03 ; iconst_0 0xac ; ireturn (return false) ; Move fast iterator forward by 1 0x2d ; aload_1 (take fast iterator) 0xb9 ; invokeinterface 0x00 0x14 ; .next() 0x01 ; 1 arg 0x00 ; unused 0x57 ; discard element ; Ensure fast iterator has next 0x2d ; aload_1 (take fast iterator) 0xb9 ; invokeinterface 0x00 0x10 ; hasNext() 0x01 0x00 0x9a ; ifne 0x00 0x05 ; jump forward by 3 if we have a next element 0x03 ; iconst_0 0xac ; ireturn

Bjorn, in register 0, is fat and lazy. He ambles along like his namesake.

0x2c ; aload_0 (take slow iterator) 0xb9 ; invokeinterface 0x00 0x14 ; .next() 0x01 0x00

Jorunn, not to be outdone, takes another stride. Her footing is sure.

0x2d ; aload_1 (take fast iterator) 0xb9 ; invokeinterface 0x00 0x14 ; .next() 0x01 0x00

With their positions on the path at hand, you check to see if they have run into one another, and if not, repeat the process once again.

0xa6 ; if_acmpne 0xff 0xd7 ; 0xffff + 1 - 41 instructions ; Return true 0x04 ; iconst_1 0xac ; ireturn

Your sixty bytes exhausted, you sigh contentedly, and inscribe the sealing runes upon your spell, before coercing each number to a single crooked byte.

; End of bytecode 0x00 0x00 ; No exceptions 0x00 0x00 ; No attributes ; End of method 0x00 0x00 ; No class attributes ] (map (fn [x] (if (instance? Long x) (unchecked-byte x) x)))))

Tim has been gently trying to steer the interview back on track. Bless him, but not too well, or he’ll follow you around on Twitter for years to come, asking for spells to soothe every computational malady that befalls him. Perhaps a ward against minor filesystem corruption would do.

Now shake the frost from your fingertips, drive your torus deep into the VM, and spin a tight-wound loop of serialization.

(defn write-class! [^DataOutputStream ds class-data] (doseq [x class-data] (condp = (class x) nil nil Long (.writeLong ds x) Integer (.writeInt ds x) Short (.writeShort ds x) Byte (.writeByte ds x) (.write ds ^bytes x)))) (defn class-bytes [class-data] (let [baos (ByteArrayOutputStream.)] (with-open [ds (DataOutputStream. baos)] (write-class! ds class-data)) (.toByteArray baos)))

“It rhymes with ‘chaos’,” you inform Tim helpfully. Nonplussed, he asks about unit tests. You weave a story of a path in the woods, which loops upon itself, in preparation.

(deftest cycle-test (let [nodes (mapv node (range 5)) list (first nodes)] (reduce link! nodes) (link! (nth nodes 3) (nth nodes 1))

Before casting the spell, you invoke the four cardinal directions, as scars around your wrist: H, J, K, L. Only the J wind answers to your kind, but it never hurts to be polite.

(deftest cycle-test (let [cycle? (partial run-bytecode (class-bytes racer) "cycle_detector.core.Racer" "Code" [Iterable])] (is (boolean (cycle? (seq list)))) (is (not (boolean (cycle? [])))) (is (not (boolean (cycle? [1 2 3])))))))) Ran 1 tests containing 3 assertions. 0 failures, 0 errors.

“Three hundred fifty-six bytes,” you declaim, and stretch in satisfaction. “Javac would have produced roughly five hundred eighty. We save a lot by omitting the stackmap and line mapping, of course, but we also cut the number of variables, and cut four superfluous astore/aload ops as well. And of course, since this class is never instantiated, we don’t need to generate an <init> method, or call super.”

Tim stares at you in mute concern. His hoodie gleams with quick-melting frost. Perhaps you have been hired.

Reach into your the pocket of your shift, and gently, with slow movements, so as not to startle him and send him scurrying back into his burrow, extend your hand, open your fingers, and offer him a walnut.

Read the whole story
18 days ago
the previous interview post had some great comments, particularly the one in the style of early William Gibson. I'm hoping to see some comments for this one in the style of ... I haven't decided. Maybe something by Arkady and Boris Strugatsky.
Share this story
2 public comments
13 days ago
"The javanisse. Surely you have heard of him! He is a small, magical man–something like a gnome–who inhabits every JVM. If you do not set out an extra constant for him, he can cause segfaults. But keep the javanisse happy, and your mutices will be fair."
Brooklyn, NY
17 days ago
“Every class begins with a babe, in a cafe.”

What are the Big Ideas in Cognitive Neuroscience?

1 Share

This year, the Cognitive Neuroscience Institute (CNI) and the Max-Planck-Society organized a symposium on Big Ideas in Cognitive Neuroscience. I enjoyed this fun forum organized by David Poeppel and Mike Gazzaniga. The format included three pairs of speakers on the topics of memory, language, and action/motor who “consider[ed] some major challenges and cutting-edge advances, from molecular mechanisms to decoding approaches to network computations.”

Co-host Marcus Raichle recalled his inspiration for the symposium: a similar Big Ideas session at the Society for Neuroscience meeting. But human neuroscience was absent from all SFN Big Ideas, so Dr. Raichle contacted Dr. Gazzaniga, who “made it happen” (along with Dr. Poeppel). The popular event was standing room only, and many couldn't even get into the Bayview Room (which was too small a venue). More context:
“Recent discussions in the neurosciences have been relentlessly reductionist. The guiding principle of this symposium is that there is no privileged level of analysis that can yield special explanatory insight into the mind/brain on its own, so ideas and techniques across levels will be necessary.”

The two hour symposium was a welcome addition to hundreds of posters and talks on highly specific empirical findings. Sometimes we must take a step back and look at the big picture. But since I'm The Neurocritic, I'll start out with some modest suggestions for next time.

  • There was no time for questions or discussion.
  • There were too many talks.
  • It would be nice for all speakers to try to bridge different levels of analysis.
  • This is a small point, but ironically the first two speakers (Gallistel, Ryan) did not talk about human neuroscience.

So my idea is to have four speakers on one topic (memory, let's say) with two at the level of Gallistel and Ryan1, and two who approach human neuroscience using different techniques. Talks are strictly limited to 20 minutes. Then there is a 20 minute panel discussion where everyone tries to consider the implications of the other levels for their own work. Then (ideally) there is time for 20 minutes of questions from the audience. However, since I'm not an expert in organizing such events, allotting 20 minutes for the audience could be excessive. So the timing could be restructured to 25 min for talks, 10-15 min panel, 5-10 min audience. Or combine the round table with audience participation.

Last year, Symposium Session 7 on Human Intracranial Electrophysiology (which included the incendiary tDCS challenge by György Buzsáki) had a round table discussion as Talk 5, which I thought was very successful.

Video of the Big Ideas symposium is now available on YouTube, but in case you don't want to watch the entire two hours, I'll present a brief summary below.

Big Box Neuroscience

Here's an idiosyncratic distillation of some major points from the symposium.

  • The brain is an information processing device in the sense of Shannon information theory.
  • The brain does not use Shannon information.
  • Memories (”engrams”) are not stored at synapses.
  • We learn entirely through spike trains.
  • The engram is inter-spike interval.
  • The engram is an emergent property.
  • Emergent properties are for losers.
  • Language is genetically predetermined.
  • There is something called mirror neural ensembles.
  • Recursion is big.
  • Architectures are important.
  • Build a bridge from networks to models of behavior.
  • Use generative models to construct theories.
  • Machine learning will save us.
  • Go back to behavioral neuroscience.

Maybe I'll explain what this all means in the next post. You can also check out the official @CogNeuroNews coverage.


1 Controversy is always entertaining, and these two had diametrically opposed views.

Read the whole story
18 days ago
Share this story
Next Page of Stories