Submissions by Harley tagged go

Back at it

A submission for Code @Home 225

I'm not going to attempt every day, but I'll try to post here a bit again. I've more-or-less been lazy about submitting here. In any case, maybe this will motivate others to remember to submit again.

Mostly I've worked on GoForth the last couple of months. It's been pretty fun hitting 100% test coverage and benchmarking most implemented words. As an example:

BenchmarkCoreWordsStackSwapCodeWord-2            2000000               638 ns/op
BenchmarkCoreWordsStackSwapFastCodeWord-2        5000000               339 ns/op

BenchmarkCoreWordsStackRotCodeWord-2             2000000               837 ns/op
BenchmarkCoreWordsStackRotFastCodeWord-2         5000000               270 ns/op 

This shows a stack swap time performing 1.8x as fast and a stack rotation performing 3.1x as fast. This one speedup was taken across any operation that was popping from the stack and then pushing a result. In most cases, an item is popped if needed, and then the top item is changed in place (or in the case of unary operators, changed in place without any push/pop.)

I also now have a basic REPL. It was surprisingly short:

package main

import (
    "fmt"

    "forth"
)

func main() {
    reader := make(chan rune)
    quit := make(chan bool)
    f := forth.NewForth()
    f.SetStdInOut()
    f.Reader(reader, quit)

    fmt.Println("Welcome to an example REPL.\nType die and press enter to exit")
    var s string
    for {
        fmt.Scan(&s)

        // Just a simple break out of the repl
        if s == "die" {
            break
        }

        for _, v := range s {
            reader <- v
        }

        reader <- ' '
    }
}

This will read from input, execute any words in the dictionary, and exit when you type " die" (without quotes and the leading space) and press enter.

Next up will likely be things like branching words and figuring out a good method for doing that.

Took another break mostly out of lack of time, other obligations, etc. I got back into it a bit tonight when I realized I hadn't updated Docker in a very long time (as in, I was on version 0.4.6 circa June 22, 2013) on my desktop at home. Upon updating that, also built the docker client for the BeagleBone Black.Unfortunately (and rather expectedly), the daemon wouldn't build.

After playing around with that a bit, I started prototyping a Forth implementation in Go. I got as far as defining a couple structures implementing a common word header (name & flags mostly.) They also satisfy a common interface which includes a codeword function. The linked version iterates through the functions executing them, while the func struct runs a single function defined in the structure. This seems like a pretty straight forward way to implement this, but I'll likely play around with other methods out of curiosity.

Cleaned up things some more. Removed utility functions that the library function basically did the same thing.Overall, the code is shaping up to be in fairly good shape to submit. I'll likely spend a bit more time on it before submitting, but I don't think I'll be able to get to the more cowbell piece that's not judged anyways.

I got the tests passing. Though, I may reevaluate how I'm readingthe binary. I also went through and fixed go vet and go lint issues. I the better commented the code.

Started reading data today and modifying things as needed. Moved some things into smaller functions.I think I know what all but two bytes of the datafile is now. Right now they're read and labeled with a /* ??? */ comment. I also have the first part converting from the raw file structure into the higher level structure.

It's not great having only a few minutes at a time to work on this, but I have the Stringer methods for most of the data structure working and a best guess data structure for the binary file.

Did a bit more on my lunch break for this. Nothing to really show yet.

I make take a break form MSP430 Forth and Pipeln to try out Go Challenge. I didn't spend much time coding, as most of my time was evaluating the binary files.

Go

A submission for Code @Home 31

Wrote a little bit of Go code and developed a better understood a simple checksumming algorithm. Also read through most of the Elm syntax at http://elm-lang.org/learn/Syntax.elm

Quick

A submission for Code @Home 30

Keeping it short since it's really late. Did a bit of Ember.js with Go and finally understand how Ember templates have to be included since there isn't an asset pipeline that embeds the Handlebars templates into the file. I could add that to pipeln, but that means I'll need to get more into filters to allow it to be extensible.

I then spent a fair amount of time with MSP430 Forth running it on an MSP430G2553 setting breakpoints and single stepping. Things seem to work up to a point, and I figured out where it's failing. However, I'm not 100% sure what needs to happen to fix it. Need to sleep on it.

I should have realized this, but using something newly written is a great way to get distracted by finding bugs in it. I spent most of my time fixing issues that cropped up in pipeln. On the plus side, it makes that project better. On the flip-side, I didn't really get that much done with Ember.js tonight. I did get a little done, but it felt like there was a fair amount of time getting my tmux session and VIM ctrlspace workspace(s) setup.

It's not the most fun part of writing software, but html/template is now at 100% coverage. Almost exactly ⅓ of the code resides in html/template, so I still have a fair few more tests to write. Sadly, I think the easiest tests are written. I don't really think the middleware piece is too hard, but really requires the assets piece to be tested. The assets piece does file access & manipulation. I can't help but think that's going to be a bit more challenging to test properly.

I also decided to say screw it and threw the code on Github: https://github.com/losinggeneration/pipeln

Spent a fair amount of time benchmarking the Go code against Sprockets (I was curious.) The Go Javascript serving isn't as fast as the Sprockets implementation currently. One thing that I can think of that could get it closer to that speed would be last modified checks and serving the preprocessed version. Overall though, as far as on my desktop, I wasn't too disappointed with the results. 20ms to serve the Ember.js app (including the debug ember.js & jquery.js files.) compared to 8ms from Rails with Unicorn. Somewhat interesting was the BeagleBone Black took roughly 1400ms to serve the same files from Go. I wasn't able to run the Rails test on BeagleBone Black hardware because...

A good portion of my time was spend trying to figure out why ember-rails on the BeagleBone Black was throwing an "undefined method 'ember'" error when trying to run rails generate ember:bootstrap.

I finished the night off writing unit tests for the template code. I got to about 60% code coverage (of ~150 lines.) Overall, I was pretty happy with how well the code behaved when I started writing tests. A few things that I expected to throw errors or junk output, ended up being handled gracefully. It's likely because I did a fair amount of iterative testing before this point.

Implementing the require_tree was fairly trivial since everything else was basically in place. I was able to make use of filepath.Walk to just walk the files and then run the Javascript processor over the files, one by one.

There are still a few issues with the implementation. For instance, using a require_tree .. is likely going to crash. The easy solution would be to disallow going up directories. A perhaps better solution would be to checksum the files, store that in a hash, and only process files that don't match a processed checksum. This is going to be slower, but should provide a better experience when using it.

Other things that still need to be done are:

  • caching
  • custom processors (think, Coffeescript, SASS, minification, etc)
  • command line tools for pre-processing assets (for caching.)

Other things that might be interesting. Getting the baseline application layout from ember-rails, getting the uncompressed jQuery, HTMLBars, & Ember.js, and then loading them from application.js with appropriate requires; everything seems to work as expected. It'll be faster, to include these normally, but it's a slightly interesting point of reference that it processed 2020288 bytes in about 20ms. Honestly, this was the end goal I was really hoping to accomplish with this project. I was really wanting to play with Ember from a non-Rails application (specifically in Go) that had Sprockets-like autoloading of Javascript files for quick iterations. The project will likely be going on Github in the next few days after I write some documentation & tests for it.

I now have the following working in javascript files to pull in others:

//= require <src>

Next up will be //= require_tree <path>

This also means that I finally figured out my named regexp's from yesterday. It basically boiled down to storing the results in a map. For example:

// Match ^//= require(_tree)? (.*)$
r, err := regexp.Compile(`^//=[[:blank:]]*require(?P<tree>_tree)?[[:blank:]]+(?P<argument>.*)$`)
if err != nil {
    return src, err
}

sm := r.FindStringSubmatch(string(line))
m := make(map[string]string)
if len(sm) > 0 {
    // Take each match and associate it with the named match
    for i, name := range r.SubexpNames() {
        // Don't include non-matches
        if sm[i] != "" {
            m[name] = sm[i]
        }
    }
}

In looking at it just now, I changed the first [[:blank:]] to be optional. Seems like that will give less "WTF?" moments when using it if a space is forgotten.

Go

A submission for Code @Home 18

I worked on some more Go asset management, but got a bit stuck on the regular expression functions with named captures. I also have my BeagleBone Black running Debian testing with systemd. Basically it was "failing" to boot last night. Turned out, dhcpc wasn't getting invoked for the ethernet, but networking was still working for USB. Once I fixed that configuration I was able to ssh right back into it to get more packages & rebuild Go 1.4.1. Also started building Ruby 2.2.0 using RVM on the BeagleBone.

More Go

A submission for Code @Home 14

The project is basically to bring a Ruby Rack Sprockets like assets serving. It's nowhere near ready, but some things are starting to work. I wrote a couple helpers for the html/templates to insert <script> & <link> tags. The basic asset lookup and serving is now working as a Negroni middleware. Currently, it offers no advantage over the provided Static middleware, but that's because the asset processing & caching isn't written yet. I'll provide a teaser of the html/template helper.

I still have some concerns with talking about a project like this when it's this early in development. The biggest one is for anyone getting any sort of expectations. I don't really want to get anyone's hopes up that this is going to be great or usable. I really should stick with projects like this, but often feel like I get developer ADD and jump to another new/interesting project.

Some things I'd like to see eventually make it into this project:

  1. Processors. Initially, it's going to be pretty basic. It'll use the Rails javascript require syntax for loading other javascript files to server more than one in a go, but it's not going to (initially) support any sort of minification, coffeescript compilation, SASS compilation, etc.
  2. Caching. This very closely relates to #1, but will likely be rudimentary put into place before #1 (because it's easier.)
template.go2kb

Go

A submission for Code @Home 13

I've got the itch to make a Go library. Without saying too much about it (in case I never release it) it could at some point be part of a web framework.